|
1 | 1 | /* eslint-disable max-depth */ |
2 | 2 | /* eslint-disable complexity */ |
3 | 3 | /* eslint-disable max-lines-per-function */ |
4 | | -import { ArrayTypeNode, EnumDeclaration, Identifier, IndexedAccessTypeNode, IntersectionTypeNode, LiteralTypeNode, Node, ts, TupleTypeNode, TypeLiteralNode, TypeNode, TypeQueryNode, TypeReferenceNode, UnionTypeNode } from 'ts-morph'; |
| 4 | +import { ArrayTypeNode, EnumDeclaration, IndexedAccessTypeNode, IntersectionTypeNode, LiteralTypeNode, Node, ts, TupleTypeNode, TypeLiteralNode, TypeNode, TypeQueryNode, TypeReferenceNode, UnionTypeNode } from 'ts-morph'; |
5 | 5 | import { handleInterfaceTypeReferences } from './handle-interfaces'; |
6 | 6 | import { compareAndCorrectMembers, orderMembers } from './interface-comparator'; |
7 | 7 | import { currentTargetSourceFile, isImportedType } from './shared'; |
@@ -65,17 +65,23 @@ function isUnknownTypeNode(typeNode: TypeNode): boolean { |
65 | 65 | } |
66 | 66 |
|
67 | 67 | function handleTargetTypeReference(targetTypeReference: TypeReferenceNode, sourceNode: TypeNode): boolean { |
| 68 | + // Skip QualifiedNames |
| 69 | + if (Node.isQualifiedName(targetTypeReference.getTypeName())) { |
| 70 | + return true; |
| 71 | + } |
| 72 | + |
68 | 73 | if (targetTypeReference.getTypeName().getText() === 'ReturnType') { |
69 | 74 | return handleIndexedReturnType(targetTypeReference, sourceNode); |
70 | 75 | } |
| 76 | + |
71 | 77 | if (targetTypeReference.getTypeName().getText() === 'Record') { |
72 | 78 | const recordEquals = handleRecord(targetTypeReference, sourceNode); |
73 | 79 | if (recordEquals) { |
74 | 80 | return true; |
75 | 81 | } |
76 | 82 | } |
77 | 83 |
|
78 | | - const targetDefinitionNode = (targetTypeReference.getTypeName() as Identifier).getDefinitionNodes()[0]; |
| 84 | + const targetDefinitionNode = getDeclarationNode(targetTypeReference); |
79 | 85 | if (Node.isTypeAliasDeclaration(targetDefinitionNode)) { |
80 | 86 | // If the target is a type alias, check the type node |
81 | 87 | // Example test case 'external template literal types' |
@@ -190,7 +196,7 @@ function handleTargetUnion(targetUnion: UnionTypeNode, sourceNode: TypeNode): bo |
190 | 196 | // If type references are TypeAliases, expand them |
191 | 197 | // Example test case 'combined union return type' |
192 | 198 | for (const typeReferenceMember of typeReferenceMembers) { |
193 | | - const definition = (typeReferenceMember.getTypeName() as Identifier).getDefinitionNodes()[0]; |
| 199 | + const definition = getDeclarationNode(typeReferenceMember); |
194 | 200 | if (Node.isTypeAliasDeclaration(definition)) { |
195 | 201 | const typeNode = definition.getTypeNode(); |
196 | 202 | if (typeNode) { |
@@ -391,7 +397,7 @@ function handleRecord(targetTypeReference: TypeReferenceNode, sourceNode: TypeNo |
391 | 397 |
|
392 | 398 | // Target=Record, Source=TypeReference |
393 | 399 | // Example test case 'numeric interface same as record' |
394 | | - const sourceDefinition = (sourceNode.getTypeName() as Identifier).getDefinitionNodes()[0]; |
| 400 | + const sourceDefinition = getDeclarationNode(sourceNode); |
395 | 401 | if (!Node.isInterfaceDeclaration(sourceDefinition)) { |
396 | 402 | return false; |
397 | 403 | } |
@@ -426,3 +432,10 @@ export function getText(typeNode: TypeNode): string { |
426 | 432 |
|
427 | 433 | return text.replace(/import\(".+?\)\./, ''); |
428 | 434 | } |
| 435 | + |
| 436 | +function getDeclarationNode(typeNode: TypeReferenceNode): Node { |
| 437 | + const typeName = typeNode.getTypeName(); |
| 438 | + const identifier = Node.isQualifiedName(typeName) ? typeName.getRight() : typeName; |
| 439 | + |
| 440 | + return identifier.getDefinitionNodes()[0]; |
| 441 | +} |
0 commit comments