From d0efe9065e41d748bfa87b7bf14a6c3bf44d49b1 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 16 Jul 2021 10:30:22 -0700 Subject: [PATCH] Dont swallow declaration emit errors when issued on nodes without names (#44995) --- src/compiler/transformers/declarations.ts | 31 +++-- ...EmitObjectAssignedDefaultExport.errors.txt | 47 +++++++ ...larationEmitObjectAssignedDefaultExport.js | 54 ++++++++ ...ionEmitObjectAssignedDefaultExport.symbols | 128 ++++++++++++++++++ ...ationEmitObjectAssignedDefaultExport.types | 94 +++++++++++++ ...larationEmitObjectAssignedDefaultExport.ts | 41 ++++++ 6 files changed, 383 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.errors.txt create mode 100644 tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.js create mode 100644 tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.symbols create mode 100644 tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.types create mode 100644 tests/cases/compiler/declarationEmitObjectAssignedDefaultExport.ts diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index d25a892cc2e..8f41a2ab0d9 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -171,33 +171,40 @@ namespace ts { } } + function errorDeclarationNameWithFallback() { + return errorNameNode ? declarationNameToString(errorNameNode) : + errorFallbackNode && getNameOfDeclaration(errorFallbackNode) ? declarationNameToString(getNameOfDeclaration(errorFallbackNode)) : + errorFallbackNode && isExportAssignment(errorFallbackNode) ? errorFallbackNode.isExportEquals ? "export=" : "default" : + "(Missing)"; // same fallback declarationNameToString uses when node is zero-width (ie, nameless) + } + function reportInaccessibleUniqueSymbolError() { - if (errorNameNode) { - context.addDiagnostic(createDiagnosticForNode(errorNameNode, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, - declarationNameToString(errorNameNode), + if (errorNameNode || errorFallbackNode) { + context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, + errorDeclarationNameWithFallback(), "unique symbol")); } } function reportCyclicStructureError() { - if (errorNameNode) { - context.addDiagnostic(createDiagnosticForNode(errorNameNode, Diagnostics.The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialized_A_type_annotation_is_necessary, - declarationNameToString(errorNameNode))); + if (errorNameNode || errorFallbackNode) { + context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialized_A_type_annotation_is_necessary, + errorDeclarationNameWithFallback())); } } function reportInaccessibleThisError() { - if (errorNameNode) { - context.addDiagnostic(createDiagnosticForNode(errorNameNode, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, - declarationNameToString(errorNameNode), + if (errorNameNode || errorFallbackNode) { + context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, + errorDeclarationNameWithFallback(), "this")); } } function reportLikelyUnsafeImportRequiredError(specifier: string) { - if (errorNameNode) { - context.addDiagnostic(createDiagnosticForNode(errorNameNode, Diagnostics.The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary, - declarationNameToString(errorNameNode), + if (errorNameNode || errorFallbackNode) { + context.addDiagnostic(createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary, + errorDeclarationNameWithFallback(), specifier)); } } diff --git a/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.errors.txt b/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.errors.txt new file mode 100644 index 00000000000..3027bf0b962 --- /dev/null +++ b/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.errors.txt @@ -0,0 +1,47 @@ +tests/cases/compiler/index.ts(7,1): error TS2742: The inferred type of 'default' cannot be named without a reference to 'styled-components/node_modules/hoist-non-react-statics'. This is likely not portable. A type annotation is necessary. + + +==== tests/cases/compiler/node_modules/styled-components/node_modules/hoist-non-react-statics/index.d.ts (0 errors) ==== + interface Statics { + "$$whatever": string; + } + declare namespace hoistNonReactStatics { + type NonReactStatics = {[X in Exclude]: T[X]} + } + export = hoistNonReactStatics; +==== tests/cases/compiler/node_modules/styled-components/index.d.ts (0 errors) ==== + import * as hoistNonReactStatics from "hoist-non-react-statics"; + export interface DefaultTheme {} + export type StyledComponent = + string + & StyledComponentBase + & hoistNonReactStatics.NonReactStatics; + export interface StyledComponentBase { + tag: TTag; + theme: TTheme; + style: TStyle; + whatever: TWhatever; + } + export interface StyledInterface { + div: (a: TemplateStringsArray) => StyledComponent<"div">; + } + + declare const styled: StyledInterface; + export default styled; +==== tests/cases/compiler/index.ts (1 errors) ==== + import styled from "styled-components"; + + const A = styled.div``; + const B = styled.div``; + export const C = styled.div``; + + export default Object.assign(A, { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + B, + ~~~~~~ + C + ~~~~~ + }); + ~~~ +!!! error TS2742: The inferred type of 'default' cannot be named without a reference to 'styled-components/node_modules/hoist-non-react-statics'. This is likely not portable. A type annotation is necessary. + \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.js b/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.js new file mode 100644 index 00000000000..ac4336bf89c --- /dev/null +++ b/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.js @@ -0,0 +1,54 @@ +//// [tests/cases/compiler/declarationEmitObjectAssignedDefaultExport.ts] //// + +//// [index.d.ts] +interface Statics { + "$$whatever": string; +} +declare namespace hoistNonReactStatics { + type NonReactStatics = {[X in Exclude]: T[X]} +} +export = hoistNonReactStatics; +//// [index.d.ts] +import * as hoistNonReactStatics from "hoist-non-react-statics"; +export interface DefaultTheme {} +export type StyledComponent = + string + & StyledComponentBase + & hoistNonReactStatics.NonReactStatics; +export interface StyledComponentBase { + tag: TTag; + theme: TTheme; + style: TStyle; + whatever: TWhatever; +} +export interface StyledInterface { + div: (a: TemplateStringsArray) => StyledComponent<"div">; +} + +declare const styled: StyledInterface; +export default styled; +//// [index.ts] +import styled from "styled-components"; + +const A = styled.div``; +const B = styled.div``; +export const C = styled.div``; + +export default Object.assign(A, { + B, + C +}); + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.C = void 0; +const styled_components_1 = require("styled-components"); +const A = styled_components_1.default.div ``; +const B = styled_components_1.default.div ``; +exports.C = styled_components_1.default.div ``; +exports.default = Object.assign(A, { + B, + C: exports.C +}); diff --git a/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.symbols b/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.symbols new file mode 100644 index 00000000000..659edb5ddca --- /dev/null +++ b/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.symbols @@ -0,0 +1,128 @@ +=== tests/cases/compiler/node_modules/styled-components/node_modules/hoist-non-react-statics/index.d.ts === +interface Statics { +>Statics : Symbol(Statics, Decl(index.d.ts, 0, 0)) + + "$$whatever": string; +>"$$whatever" : Symbol(Statics["$$whatever"], Decl(index.d.ts, 0, 19)) +} +declare namespace hoistNonReactStatics { +>hoistNonReactStatics : Symbol(hoistNonReactStatics, Decl(index.d.ts, 2, 1)) + + type NonReactStatics = {[X in Exclude]: T[X]} +>NonReactStatics : Symbol(NonReactStatics, Decl(index.d.ts, 3, 40)) +>T : Symbol(T, Decl(index.d.ts, 4, 25)) +>X : Symbol(X, Decl(index.d.ts, 4, 32)) +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(index.d.ts, 4, 25)) +>Statics : Symbol(Statics, Decl(index.d.ts, 0, 0)) +>T : Symbol(T, Decl(index.d.ts, 4, 25)) +>X : Symbol(X, Decl(index.d.ts, 4, 32)) +} +export = hoistNonReactStatics; +>hoistNonReactStatics : Symbol(hoistNonReactStatics, Decl(index.d.ts, 2, 1)) + +=== tests/cases/compiler/node_modules/styled-components/index.d.ts === +import * as hoistNonReactStatics from "hoist-non-react-statics"; +>hoistNonReactStatics : Symbol(hoistNonReactStatics, Decl(index.d.ts, 0, 6)) + +export interface DefaultTheme {} +>DefaultTheme : Symbol(DefaultTheme, Decl(index.d.ts, 0, 64)) + +export type StyledComponent = +>StyledComponent : Symbol(StyledComponent, Decl(index.d.ts, 1, 32)) +>TTag : Symbol(TTag, Decl(index.d.ts, 2, 28)) +>TTheme : Symbol(TTheme, Decl(index.d.ts, 2, 48)) +>DefaultTheme : Symbol(DefaultTheme, Decl(index.d.ts, 0, 64)) +>TStyle : Symbol(TStyle, Decl(index.d.ts, 2, 71)) +>TWhatever : Symbol(TWhatever, Decl(index.d.ts, 2, 84)) + + string + & StyledComponentBase +>StyledComponentBase : Symbol(StyledComponentBase, Decl(index.d.ts, 5, 49)) +>TTag : Symbol(TTag, Decl(index.d.ts, 2, 28)) +>TTheme : Symbol(TTheme, Decl(index.d.ts, 2, 48)) +>TStyle : Symbol(TStyle, Decl(index.d.ts, 2, 71)) +>TWhatever : Symbol(TWhatever, Decl(index.d.ts, 2, 84)) + + & hoistNonReactStatics.NonReactStatics; +>hoistNonReactStatics : Symbol(hoistNonReactStatics, Decl(index.d.ts, 0, 6)) +>NonReactStatics : Symbol(hoistNonReactStatics.NonReactStatics, Decl(index.d.ts, 3, 40)) +>TTag : Symbol(TTag, Decl(index.d.ts, 2, 28)) + +export interface StyledComponentBase { +>StyledComponentBase : Symbol(StyledComponentBase, Decl(index.d.ts, 5, 49)) +>TTag : Symbol(TTag, Decl(index.d.ts, 6, 37)) +>TTheme : Symbol(TTheme, Decl(index.d.ts, 6, 57)) +>DefaultTheme : Symbol(DefaultTheme, Decl(index.d.ts, 0, 64)) +>TStyle : Symbol(TStyle, Decl(index.d.ts, 6, 80)) +>TWhatever : Symbol(TWhatever, Decl(index.d.ts, 6, 93)) + + tag: TTag; +>tag : Symbol(StyledComponentBase.tag, Decl(index.d.ts, 6, 114)) +>TTag : Symbol(TTag, Decl(index.d.ts, 6, 37)) + + theme: TTheme; +>theme : Symbol(StyledComponentBase.theme, Decl(index.d.ts, 7, 14)) +>TTheme : Symbol(TTheme, Decl(index.d.ts, 6, 57)) + + style: TStyle; +>style : Symbol(StyledComponentBase.style, Decl(index.d.ts, 8, 18)) +>TStyle : Symbol(TStyle, Decl(index.d.ts, 6, 80)) + + whatever: TWhatever; +>whatever : Symbol(StyledComponentBase.whatever, Decl(index.d.ts, 9, 18)) +>TWhatever : Symbol(TWhatever, Decl(index.d.ts, 6, 93)) +} +export interface StyledInterface { +>StyledInterface : Symbol(StyledInterface, Decl(index.d.ts, 11, 1)) + + div: (a: TemplateStringsArray) => StyledComponent<"div">; +>div : Symbol(StyledInterface.div, Decl(index.d.ts, 12, 34)) +>a : Symbol(a, Decl(index.d.ts, 13, 10)) +>TemplateStringsArray : Symbol(TemplateStringsArray, Decl(lib.es5.d.ts, --, --)) +>StyledComponent : Symbol(StyledComponent, Decl(index.d.ts, 1, 32)) +} + +declare const styled: StyledInterface; +>styled : Symbol(styled, Decl(index.d.ts, 16, 13)) +>StyledInterface : Symbol(StyledInterface, Decl(index.d.ts, 11, 1)) + +export default styled; +>styled : Symbol(styled, Decl(index.d.ts, 16, 13)) + +=== tests/cases/compiler/index.ts === +import styled from "styled-components"; +>styled : Symbol(styled, Decl(index.ts, 0, 6)) + +const A = styled.div``; +>A : Symbol(A, Decl(index.ts, 2, 5)) +>styled.div : Symbol(StyledInterface.div, Decl(index.d.ts, 12, 34)) +>styled : Symbol(styled, Decl(index.ts, 0, 6)) +>div : Symbol(StyledInterface.div, Decl(index.d.ts, 12, 34)) + +const B = styled.div``; +>B : Symbol(B, Decl(index.ts, 3, 5)) +>styled.div : Symbol(StyledInterface.div, Decl(index.d.ts, 12, 34)) +>styled : Symbol(styled, Decl(index.ts, 0, 6)) +>div : Symbol(StyledInterface.div, Decl(index.d.ts, 12, 34)) + +export const C = styled.div``; +>C : Symbol(C, Decl(index.ts, 4, 12)) +>styled.div : Symbol(StyledInterface.div, Decl(index.d.ts, 12, 34)) +>styled : Symbol(styled, Decl(index.ts, 0, 6)) +>div : Symbol(StyledInterface.div, Decl(index.d.ts, 12, 34)) + +export default Object.assign(A, { +>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>A : Symbol(A, Decl(index.ts, 2, 5)) + + B, +>B : Symbol(B, Decl(index.ts, 6, 33)) + + C +>C : Symbol(C, Decl(index.ts, 7, 6)) + +}); + diff --git a/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.types b/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.types new file mode 100644 index 00000000000..b95d5a76463 --- /dev/null +++ b/tests/baselines/reference/declarationEmitObjectAssignedDefaultExport.types @@ -0,0 +1,94 @@ +=== tests/cases/compiler/node_modules/styled-components/node_modules/hoist-non-react-statics/index.d.ts === +interface Statics { + "$$whatever": string; +>"$$whatever" : string +} +declare namespace hoistNonReactStatics { + type NonReactStatics = {[X in Exclude]: T[X]} +>NonReactStatics : NonReactStatics +} +export = hoistNonReactStatics; +>hoistNonReactStatics : any + +=== tests/cases/compiler/node_modules/styled-components/index.d.ts === +import * as hoistNonReactStatics from "hoist-non-react-statics"; +>hoistNonReactStatics : any + +export interface DefaultTheme {} +export type StyledComponent = +>StyledComponent : StyledComponent + + string + & StyledComponentBase + & hoistNonReactStatics.NonReactStatics; +>hoistNonReactStatics : any + +export interface StyledComponentBase { + tag: TTag; +>tag : TTag + + theme: TTheme; +>theme : TTheme + + style: TStyle; +>style : TStyle + + whatever: TWhatever; +>whatever : TWhatever +} +export interface StyledInterface { + div: (a: TemplateStringsArray) => StyledComponent<"div">; +>div : (a: TemplateStringsArray) => StyledComponent<"div"> +>a : TemplateStringsArray +} + +declare const styled: StyledInterface; +>styled : StyledInterface + +export default styled; +>styled : StyledInterface + +=== tests/cases/compiler/index.ts === +import styled from "styled-components"; +>styled : import("tests/cases/compiler/node_modules/styled-components/index").StyledInterface + +const A = styled.div``; +>A : import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>styled.div`` : import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>styled.div : (a: TemplateStringsArray) => import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>styled : import("tests/cases/compiler/node_modules/styled-components/index").StyledInterface +>div : (a: TemplateStringsArray) => import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>`` : "" + +const B = styled.div``; +>B : import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>styled.div`` : import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>styled.div : (a: TemplateStringsArray) => import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>styled : import("tests/cases/compiler/node_modules/styled-components/index").StyledInterface +>div : (a: TemplateStringsArray) => import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>`` : "" + +export const C = styled.div``; +>C : import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>styled.div`` : import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>styled.div : (a: TemplateStringsArray) => import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>styled : import("tests/cases/compiler/node_modules/styled-components/index").StyledInterface +>div : (a: TemplateStringsArray) => import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>`` : "" + +export default Object.assign(A, { +>Object.assign(A, { B, C}) : string & import("tests/cases/compiler/node_modules/styled-components/index").StyledComponentBase<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> & import("tests/cases/compiler/node_modules/styled-components/node_modules/hoist-non-react-statics/index").NonReactStatics<"div"> & { B: import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never>; C: import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never>; } +>Object.assign : { (target: T, source: U): T & U; (target: T, source1: U, source2: V): T & U & V; (target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; } +>Object : ObjectConstructor +>assign : { (target: T, source: U): T & U; (target: T, source1: U, source2: V): T & U & V; (target: T, source1: U, source2: V, source3: W): T & U & V & W; (target: object, ...sources: any[]): any; } +>A : import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> +>{ B, C} : { B: import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never>; C: import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never>; } + + B, +>B : import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> + + C +>C : import("tests/cases/compiler/node_modules/styled-components/index").StyledComponent<"div", import("tests/cases/compiler/node_modules/styled-components/index").DefaultTheme, {}, never> + +}); + diff --git a/tests/cases/compiler/declarationEmitObjectAssignedDefaultExport.ts b/tests/cases/compiler/declarationEmitObjectAssignedDefaultExport.ts new file mode 100644 index 00000000000..e83dffc3b21 --- /dev/null +++ b/tests/cases/compiler/declarationEmitObjectAssignedDefaultExport.ts @@ -0,0 +1,41 @@ +// @target: es6 +// @module: commonjs +// @declaration: true +// @filename: node_modules/styled-components/node_modules/hoist-non-react-statics/index.d.ts +interface Statics { + "$$whatever": string; +} +declare namespace hoistNonReactStatics { + type NonReactStatics = {[X in Exclude]: T[X]} +} +export = hoistNonReactStatics; +// @filename: node_modules/styled-components/index.d.ts +import * as hoistNonReactStatics from "hoist-non-react-statics"; +export interface DefaultTheme {} +export type StyledComponent = + string + & StyledComponentBase + & hoistNonReactStatics.NonReactStatics; +export interface StyledComponentBase { + tag: TTag; + theme: TTheme; + style: TStyle; + whatever: TWhatever; +} +export interface StyledInterface { + div: (a: TemplateStringsArray) => StyledComponent<"div">; +} + +declare const styled: StyledInterface; +export default styled; +// @filename: index.ts +import styled from "styled-components"; + +const A = styled.div``; +const B = styled.div``; +export const C = styled.div``; + +export default Object.assign(A, { + B, + C +});