visitClassBody()

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('();');
      }
    }
  }