From 07d56fb01d7937d78611388b1fca9a0deea1b8a5 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 1 Dec 2020 12:19:12 -0800 Subject: [PATCH] addImplementationSuccessElaboration admits declarations with no symbol (#41758) --- src/compiler/checker.ts | 6 ++-- ...jsxCallElaborationCheckNoCrash1.errors.txt | 19 ++++++++++++ .../jsxCallElaborationCheckNoCrash1.js | 26 ++++++++++++++++ .../jsxCallElaborationCheckNoCrash1.symbols | 31 +++++++++++++++++++ .../jsxCallElaborationCheckNoCrash1.types | 30 ++++++++++++++++++ .../jsxCallElaborationCheckNoCrash1.tsx | 13 ++++++++ 6 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/jsxCallElaborationCheckNoCrash1.errors.txt create mode 100644 tests/baselines/reference/jsxCallElaborationCheckNoCrash1.js create mode 100644 tests/baselines/reference/jsxCallElaborationCheckNoCrash1.symbols create mode 100644 tests/baselines/reference/jsxCallElaborationCheckNoCrash1.types create mode 100644 tests/cases/compiler/jsxCallElaborationCheckNoCrash1.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dfdb9dd32de24..97d41c9923e87 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27448,9 +27448,9 @@ namespace ts { const oldCandidateForArgumentArityError = candidateForArgumentArityError; const oldCandidateForTypeArgumentError = candidateForTypeArgumentError; - const declCount = length(failed.declaration?.symbol.declarations); - const isOverload = declCount > 1; - const implDecl = isOverload ? find(failed.declaration?.symbol.declarations || emptyArray, d => isFunctionLikeDeclaration(d) && nodeIsPresent(d.body)) : undefined; + const failedSignatureDeclarations = failed.declaration?.symbol?.declarations || emptyArray; + const isOverload = failedSignatureDeclarations.length > 1; + const implDecl = isOverload ? find(failedSignatureDeclarations, d => isFunctionLikeDeclaration(d) && nodeIsPresent(d.body)) : undefined; if (implDecl) { const candidate = getSignatureFromDeclaration(implDecl as FunctionLikeDeclaration); const isSingleNonGenericCandidate = !candidate.typeParameters; diff --git a/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.errors.txt b/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.errors.txt new file mode 100644 index 0000000000000..8cdf46ededba8 --- /dev/null +++ b/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/jsxCallElaborationCheckNoCrash1.tsx(10,29): error TS2322: Type '{}' is not assignable to type 'LibraryManagedAttributes, HTMLDivElement>>'. + + +==== tests/cases/compiler/jsxCallElaborationCheckNoCrash1.tsx (1 errors) ==== + /// + + import * as React from "react"; + + type Tags = "span" | "div"; + + export const Hoc = ( + TagElement: Tag, + ): React.SFC => { + const Component = () => ; + ~~~~~~~~~~ +!!! error TS2322: Type '{}' is not assignable to type 'LibraryManagedAttributes, HTMLDivElement>>'. + return Component; + }; + \ No newline at end of file diff --git a/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.js b/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.js new file mode 100644 index 0000000000000..01c751167d200 --- /dev/null +++ b/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.js @@ -0,0 +1,26 @@ +//// [jsxCallElaborationCheckNoCrash1.tsx] +/// + +import * as React from "react"; + +type Tags = "span" | "div"; + +export const Hoc = ( + TagElement: Tag, +): React.SFC => { + const Component = () => ; + return Component; +}; + + +//// [jsxCallElaborationCheckNoCrash1.js] +"use strict"; +/// +exports.__esModule = true; +exports.Hoc = void 0; +var React = require("react"); +var Hoc = function (TagElement) { + var Component = function () { return React.createElement(TagElement, null); }; + return Component; +}; +exports.Hoc = Hoc; diff --git a/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.symbols b/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.symbols new file mode 100644 index 0000000000000..cb10cdc489adc --- /dev/null +++ b/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/jsxCallElaborationCheckNoCrash1.tsx === +/// + +import * as React from "react"; +>React : Symbol(React, Decl(jsxCallElaborationCheckNoCrash1.tsx, 2, 6)) + +type Tags = "span" | "div"; +>Tags : Symbol(Tags, Decl(jsxCallElaborationCheckNoCrash1.tsx, 2, 31)) + +export const Hoc = ( +>Hoc : Symbol(Hoc, Decl(jsxCallElaborationCheckNoCrash1.tsx, 6, 12)) +>Tag : Symbol(Tag, Decl(jsxCallElaborationCheckNoCrash1.tsx, 6, 20)) +>Tags : Symbol(Tags, Decl(jsxCallElaborationCheckNoCrash1.tsx, 2, 31)) + + TagElement: Tag, +>TagElement : Symbol(TagElement, Decl(jsxCallElaborationCheckNoCrash1.tsx, 6, 38)) +>Tag : Symbol(Tag, Decl(jsxCallElaborationCheckNoCrash1.tsx, 6, 20)) + +): React.SFC => { +>React : Symbol(React, Decl(jsxCallElaborationCheckNoCrash1.tsx, 2, 6)) +>SFC : Symbol(React.SFC, Decl(react16.d.ts, 400, 9)) + + const Component = () => ; +>Component : Symbol(Component, Decl(jsxCallElaborationCheckNoCrash1.tsx, 9, 8)) +>TagElement : Symbol(TagElement, Decl(jsxCallElaborationCheckNoCrash1.tsx, 6, 38)) + + return Component; +>Component : Symbol(Component, Decl(jsxCallElaborationCheckNoCrash1.tsx, 9, 8)) + +}; + diff --git a/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.types b/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.types new file mode 100644 index 0000000000000..d3fb0d602549b --- /dev/null +++ b/tests/baselines/reference/jsxCallElaborationCheckNoCrash1.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/jsxCallElaborationCheckNoCrash1.tsx === +/// + +import * as React from "react"; +>React : typeof React + +type Tags = "span" | "div"; +>Tags : Tags + +export const Hoc = ( +>Hoc : (TagElement: Tag) => React.SFC +>( TagElement: Tag,): React.SFC => { const Component = () => ; return Component;} : (TagElement: Tag) => React.SFC + + TagElement: Tag, +>TagElement : Tag + +): React.SFC => { +>React : any + + const Component = () => ; +>Component : () => JSX.Element +>() => : () => JSX.Element +> : JSX.Element +>TagElement : Tag + + return Component; +>Component : () => JSX.Element + +}; + diff --git a/tests/cases/compiler/jsxCallElaborationCheckNoCrash1.tsx b/tests/cases/compiler/jsxCallElaborationCheckNoCrash1.tsx new file mode 100644 index 0000000000000..1121f5259fede --- /dev/null +++ b/tests/cases/compiler/jsxCallElaborationCheckNoCrash1.tsx @@ -0,0 +1,13 @@ +// @jsx: react +/// + +import * as React from "react"; + +type Tags = "span" | "div"; + +export const Hoc = ( + TagElement: Tag, +): React.SFC => { + const Component = () => ; + return Component; +};