in lib/declaration.ts [231:274]
visitClassBody(decl: base.ClassLike|ts.TypeLiteralNode, name: ts.Identifier) {
let properties: ts.PropertyDeclaration[] = [];
let isPropertyBag = false;
if (ts.isInterfaceDeclaration(decl)) {
const extendedInterfaceDecl = decl as base.ExtendedInterfaceDeclaration;
const constructedType = extendedInterfaceDecl.constructedType;
if (constructedType) {
// If this interface is the upgraded version of a variable whose type contained a
// constructor, we must check the type hierarchy of the original type, as well as the
// properties of the new merged interface.
if (ts.isInterfaceDeclaration(constructedType)) {
isPropertyBag = this.hasOnlyProperties(constructedType, properties) &&
this.hasOnlyPropertiesHelper(decl.members, properties);
} else if (ts.isTypeLiteralNode(constructedType)) {
isPropertyBag = this.hasOnlyPropertiesHelper(decl.members, properties);
}
} else {
isPropertyBag = this.hasOnlyProperties(decl, properties);
}
} else if (ts.isTypeLiteralNode(decl)) {
isPropertyBag = this.hasOnlyPropertiesHelper(decl.members, properties);
}
this.visitMergingOverloads(decl.members);
if (isPropertyBag) {
const propertiesWithValidNames = properties.filter((p) => {
return isValidIdentifier(p.name);
});
this.emit('external factory');
this.fc.visitTypeName(name);
if (propertiesWithValidNames.length) {
this.emitNoSpace('({');
for (let i = 0; i < propertiesWithValidNames.length; i++) {
if (i > 0) this.emitNoSpace(',');
let p = propertiesWithValidNames[i];
this.visit(p.type);
this.visit(p.name);
}
this.emitNoSpace('});');
} else {
this.emitNoSpace('();');
}
}
}