* Extracts the interface definition from the source file.
(
interfaceName: string,
)
| 126 | * Extracts the interface definition from the source file. |
| 127 | */ |
| 128 | protected extractInterfaceDefinition( |
| 129 | interfaceName: string, |
| 130 | ): InterfaceDefinition { |
| 131 | const definition: InterfaceDefinition = { |
| 132 | name: interfaceName, |
| 133 | properties: [], |
| 134 | }; |
| 135 | const visit = (node: ts.Node) => { |
| 136 | if (ts.isInterfaceDeclaration(node) && node.name.text === interfaceName) { |
| 137 | let omittedProperties: Set<string> = new Set(); |
| 138 | |
| 139 | // Check for extended interfaces |
| 140 | if (node.heritageClauses && node.heritageClauses.length > 0) { |
| 141 | const firstClause = node.heritageClauses[0]; |
| 142 | firstClause.types.forEach((type) => { |
| 143 | const typeName = type.expression.getText(this.sourceFile); |
| 144 | let extendedInterfaceName = typeName; |
| 145 | |
| 146 | // Check if the type is an Omit |
| 147 | if (typeName.startsWith("Omit")) { |
| 148 | const omitArgs = type.typeArguments; |
| 149 | if (omitArgs && omitArgs.length > 0) { |
| 150 | extendedInterfaceName = omitArgs[0].getText(this.sourceFile); |
| 151 | if (omitArgs.length > 1) { |
| 152 | const omittedProps = omitArgs[1]; |
| 153 | if (ts.isUnionTypeNode(omittedProps)) { |
| 154 | omittedProps.types.forEach((prop) => { |
| 155 | omittedProperties.add( |
| 156 | prop.getText(this.sourceFile).replace(/['"]/g, ""), |
| 157 | ); |
| 158 | }); |
| 159 | } else if (ts.isLiteralTypeNode(omittedProps)) { |
| 160 | omittedProperties.add( |
| 161 | omittedProps |
| 162 | .getText(this.sourceFile) |
| 163 | .replace(/['"]/g, ""), |
| 164 | ); |
| 165 | } |
| 166 | } |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | const extendedInterfaceFilePath = this.findTypeDeclaration( |
| 171 | extendedInterfaceName, |
| 172 | ); |
| 173 | if (extendedInterfaceFilePath) { |
| 174 | // Parse the extended interface file and extract its definition |
| 175 | const extendedInterfaceSource = new SourceFile( |
| 176 | extendedInterfaceFilePath, |
| 177 | ); |
| 178 | extendedInterfaceSource.parse(); |
| 179 | const extendedDefinition = |
| 180 | extendedInterfaceSource.extractInterfaceDefinition( |
| 181 | extendedInterfaceName, |
| 182 | ); |
| 183 | // Merge properties from the extended interface, excluding omitted properties |
| 184 | extendedDefinition.properties.forEach((prop) => { |
| 185 | if (!omittedProperties.has(prop.name)) { |
no test coverage detected