diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 973c040a769..02d590bb8b6 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -29,7 +29,7 @@ namespace ts.GoToDefinition { const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node); // Don't go to the component constructor definition for a JSX element, just go to the component definition. - if (calledDeclaration && !(isJsxOpeningLikeElement(node.parent) && isConstructorDeclaration(calledDeclaration))) { + if (calledDeclaration && !(isJsxOpeningLikeElement(node.parent) && isConstructorLike(calledDeclaration))) { const sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration); // For a function, if this is the original function definition, return just sigInfo. // If this is the original constructor definition, parent is the class. @@ -319,4 +319,15 @@ namespace ts.GoToDefinition { // Don't go to a function type, go to the value having that type. return tryCast(signature && signature.declaration, (d): d is SignatureDeclaration => isFunctionLike(d) && !isFunctionTypeNode(d)); } + + function isConstructorLike(node: Node): boolean { + switch (node.kind) { + case SyntaxKind.Constructor: + case SyntaxKind.ConstructorType: + case SyntaxKind.ConstructSignature: + return true; + default: + return false; + } + } } diff --git a/tests/cases/fourslash/goToDefinitionSignatureAlias.ts b/tests/cases/fourslash/goToDefinitionSignatureAlias.ts index 909322582eb..4ace3635cc8 100644 --- a/tests/cases/fourslash/goToDefinitionSignatureAlias.ts +++ b/tests/cases/fourslash/goToDefinitionSignatureAlias.ts @@ -21,9 +21,20 @@ ////o.[|/*useM*/m|](); ////class Component { /*componentCtr*/constructor(props: {}) {} } +////type ComponentClass = /*ComponentClass*/new () => Component; +////interface ComponentClass2 { /*ComponentClass2*/new(): Component; } +//// ////class /*MyComponent*/MyComponent extends Component {} -////<[|/*jsxMyComponent*/MyComponent|] /> +////<[|/*jsxMyComponent*/MyComponent|] />; ////new [|/*newMyComponent*/MyComponent|]({}); +//// +////declare const /*MyComponent2*/MyComponent2: ComponentClass; +////<[|/*jsxMyComponent2*/MyComponent2|] />; +////new [|/*newMyComponent2*/MyComponent2|](); +//// +////declare const /*MyComponent3*/MyComponent3: ComponentClass2; +////<[|/*jsxMyComponent3*/MyComponent3|] />; +////new [|/*newMyComponent3*/MyComponent3|](); verify.noErrors(); @@ -38,4 +49,10 @@ verify.goToDefinition({ jsxMyComponent: "MyComponent", newMyComponent: ["MyComponent", "componentCtr"], + + jsxMyComponent2: "MyComponent2", + newMyComponent2: ["MyComponent2", "ComponentClass"], + + jsxMyComponent3: "MyComponent3", + newMyComponent3: ["MyComponent3", "ComponentClass2"], });