From 7ff7dcc27ddca446e6baca6fb7fbab5d790c8eb6 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 8 Aug 2018 15:17:30 -0700 Subject: [PATCH 1/2] Check the ambientness of a symbol name before attempting to trim it --- src/compiler/checker.ts | 45 ++++++----- src/compiler/moduleSpecifiers.ts | 15 +++- src/compiler/utilities.ts | 4 + .../reference/augmentExportEquals3.types | 4 +- .../reference/augmentExportEquals3_1.types | 4 +- .../reference/augmentExportEquals4.types | 4 +- .../reference/augmentExportEquals4_1.types | 4 +- .../reference/augmentExportEquals5.types | 4 +- .../reference/augmentExportEquals6.types | 4 +- .../reference/augmentExportEquals6_1.types | 4 +- ...mentationDuringSyntheticDefaultCheck.types | 4 +- ...eactTransitiveImportHasValidDeclaration.js | 49 ++++++++++++ ...ransitiveImportHasValidDeclaration.symbols | 77 +++++++++++++++++++ ...tTransitiveImportHasValidDeclaration.types | 59 ++++++++++++++ .../reference/umd-augmentation-3.types | 4 +- .../reference/umd-augmentation-4.types | 4 +- ...eactTransitiveImportHasValidDeclaration.ts | 33 ++++++++ 17 files changed, 278 insertions(+), 44 deletions(-) create mode 100644 tests/baselines/reference/reactTransitiveImportHasValidDeclaration.js create mode 100644 tests/baselines/reference/reactTransitiveImportHasValidDeclaration.symbols create mode 100644 tests/baselines/reference/reactTransitiveImportHasValidDeclaration.types create mode 100644 tests/cases/compiler/reactTransitiveImportHasValidDeclaration.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 649979e412084..78f7d44ab1ae6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3880,31 +3880,34 @@ namespace ts { } } } - return (symbol.escapedName as string).substring(1, (symbol.escapedName as string).length - 1); - } - else { - if (!context.enclosingDeclaration || !context.tracker.moduleResolverHost) { - // If there's no context declaration, we can't lookup a non-ambient specifier, so we just use the symbol name + if (ambientModuleSymbolRegex.test(symbol.escapedName as string)) { return (symbol.escapedName as string).substring(1, (symbol.escapedName as string).length - 1); } - const contextFile = getSourceFileOfNode(getOriginalNode(context.enclosingDeclaration)); - const links = getSymbolLinks(symbol); - let specifier = links.specifierCache && links.specifierCache.get(contextFile.path); - if (!specifier) { - specifier = moduleSpecifiers.getModuleSpecifierForDeclarationFile( - symbol, - compilerOptions, - contextFile, - context.tracker.moduleResolverHost, - context.tracker.moduleResolverHost.getSourceFiles!(), // TODO: GH#18217 - { importModuleSpecifierPreference: "non-relative" }, - host.redirectTargetsMap, - ); - links.specifierCache = links.specifierCache || createMap(); - links.specifierCache.set(contextFile.path, specifier); + } + if (!context.enclosingDeclaration || !context.tracker.moduleResolverHost) { + // If there's no context declaration, we can't lookup a non-ambient specifier, so we just use the symbol name + if (ambientModuleSymbolRegex.test(symbol.escapedName as string)) { + return (symbol.escapedName as string).substring(1, (symbol.escapedName as string).length - 1); } - return specifier; + return getSourceFileOfNode(getNonAugmentationDeclaration(symbol)!).fileName; // A resolver may not be provided for baselines and errors - in those cases we use the fileName in full + } + const contextFile = getSourceFileOfNode(getOriginalNode(context.enclosingDeclaration)); + const links = getSymbolLinks(symbol); + let specifier = links.specifierCache && links.specifierCache.get(contextFile.path); + if (!specifier) { + specifier = moduleSpecifiers.getModuleSpecifierForDeclarationFile( + symbol, + compilerOptions, + contextFile, + context.tracker.moduleResolverHost, + context.tracker.moduleResolverHost.getSourceFiles!(), // TODO: GH#18217 + { importModuleSpecifierPreference: "non-relative" }, + host.redirectTargetsMap, + ); + links.specifierCache = links.specifierCache || createMap(); + links.specifierCache.set(contextFile.path, specifier); } + return specifier; } function symbolToTypeNode(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags, overrideTypeArguments?: ReadonlyArray): TypeNode { diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index a82f5b854e12a..451158e2423d2 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -51,7 +51,7 @@ namespace ts.moduleSpecifiers { if (!files) { return Debug.fail("Files list must be present to resolve symlinks in specifier resolution"); } - const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration); + const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol)); const modulePaths = getAllModulePaths(files, importingSourceFile.path, moduleSourceFile.fileName, info.getCanonicalFileName, host, redirectTargetsMap); const global = mapDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions)); @@ -232,8 +232,17 @@ namespace ts.moduleSpecifiers { } function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol): string | undefined { - const decl = moduleSymbol.valueDeclaration; - if (isModuleDeclaration(decl) && isStringLiteral(decl.name)) { + const decl = forEach(moduleSymbol.declarations, d => { + if (!isAmbientModule(d)) return; + if (isExternalModuleAugmentation(d)) { + if (!isExternalModuleNameRelative(getTextOfIdentifierOrLiteral(d.name))) { + return d; + } + return; + } + return d; + }); + if (decl && isModuleDeclaration(decl) && isStringLiteral(decl.name)) { return decl.name.text; } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b285a9878486e..0248b2fd30c9e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -638,6 +638,10 @@ namespace ts { return false; } + export function getNonAugmentationDeclaration(symbol: Symbol) { + return forEach(symbol.declarations, d => isExternalModuleAugmentation(d) ? undefined : d); + } + export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) { return isExternalModule(node) || compilerOptions.isolatedModules || ((getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS) && !!node.commonJsModuleIndicator); } diff --git a/tests/baselines/reference/augmentExportEquals3.types b/tests/baselines/reference/augmentExportEquals3.types index 5e1b832ec07a1..87290d7415046 100644 --- a/tests/baselines/reference/augmentExportEquals3.types +++ b/tests/baselines/reference/augmentExportEquals3.types @@ -1,9 +1,9 @@ === tests/cases/compiler/file1.ts === function foo() {} ->foo : typeof import("o") +>foo : typeof import("tests/cases/compiler/file1.ts") namespace foo { ->foo : typeof import("o") +>foo : typeof import("tests/cases/compiler/file1.ts") export var v = 1; >v : number diff --git a/tests/baselines/reference/augmentExportEquals3_1.types b/tests/baselines/reference/augmentExportEquals3_1.types index 94f79d50429ef..291dad7e9c7d5 100644 --- a/tests/baselines/reference/augmentExportEquals3_1.types +++ b/tests/baselines/reference/augmentExportEquals3_1.types @@ -3,10 +3,10 @@ declare module "file1" { >"file1" : typeof import("file1") function foo(): void; ->foo : typeof import("o") +>foo : typeof import("tests/cases/compiler/file1.d.ts") namespace foo { ->foo : typeof import("o") +>foo : typeof import("tests/cases/compiler/file1.d.ts") export var v: number; >v : number diff --git a/tests/baselines/reference/augmentExportEquals4.types b/tests/baselines/reference/augmentExportEquals4.types index a18268d9e8ae9..5e4574c815cc5 100644 --- a/tests/baselines/reference/augmentExportEquals4.types +++ b/tests/baselines/reference/augmentExportEquals4.types @@ -1,9 +1,9 @@ === tests/cases/compiler/file1.ts === class foo {} ->foo : import("o") +>foo : import("tests/cases/compiler/file1.ts") namespace foo { ->foo : typeof import("o") +>foo : typeof import("tests/cases/compiler/file1.ts") export var v = 1; >v : number diff --git a/tests/baselines/reference/augmentExportEquals4_1.types b/tests/baselines/reference/augmentExportEquals4_1.types index a86bb2e89ec8f..b437468d3f9c9 100644 --- a/tests/baselines/reference/augmentExportEquals4_1.types +++ b/tests/baselines/reference/augmentExportEquals4_1.types @@ -3,10 +3,10 @@ declare module "file1" { >"file1" : typeof import("file1") class foo {} ->foo : import("o") +>foo : import("tests/cases/compiler/file1.d.ts") namespace foo { ->foo : typeof import("o") +>foo : typeof import("tests/cases/compiler/file1.d.ts") export var v: number; >v : number diff --git a/tests/baselines/reference/augmentExportEquals5.types b/tests/baselines/reference/augmentExportEquals5.types index 8c5dcb14173f6..d6065df836022 100644 --- a/tests/baselines/reference/augmentExportEquals5.types +++ b/tests/baselines/reference/augmentExportEquals5.types @@ -9,11 +9,11 @@ declare module "express" { >"express" : typeof import("express") function e(): e.Express; ->e : typeof import("e") +>e : typeof import("tests/cases/compiler/express.d.ts") >e : any namespace e { ->e : typeof import("e") +>e : typeof import("tests/cases/compiler/express.d.ts") interface IRoute { all(...handler: RequestHandler[]): IRoute; diff --git a/tests/baselines/reference/augmentExportEquals6.types b/tests/baselines/reference/augmentExportEquals6.types index 272a4fd58754a..3a404744f0781 100644 --- a/tests/baselines/reference/augmentExportEquals6.types +++ b/tests/baselines/reference/augmentExportEquals6.types @@ -1,9 +1,9 @@ === tests/cases/compiler/file1.ts === class foo {} ->foo : import("o") +>foo : import("tests/cases/compiler/file1.ts") namespace foo { ->foo : typeof import("o") +>foo : typeof import("tests/cases/compiler/file1.ts") export class A {} >A : A diff --git a/tests/baselines/reference/augmentExportEquals6_1.types b/tests/baselines/reference/augmentExportEquals6_1.types index d8aed819ba539..c34d135d704ee 100644 --- a/tests/baselines/reference/augmentExportEquals6_1.types +++ b/tests/baselines/reference/augmentExportEquals6_1.types @@ -3,10 +3,10 @@ declare module "file1" { >"file1" : typeof import("file1") class foo {} ->foo : import("o") +>foo : import("tests/cases/compiler/file1.d.ts") namespace foo { ->foo : typeof import("o") +>foo : typeof import("tests/cases/compiler/file1.d.ts") class A {} >A : A diff --git a/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.types b/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.types index ceda676301462..3ee42ec79aad3 100644 --- a/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.types +++ b/tests/baselines/reference/moduleAugmentationDuringSyntheticDefaultCheck.types @@ -6,7 +6,7 @@ import moment = require("moment-timezone"); === tests/cases/compiler/node_modules/moment/index.d.ts === declare function moment(): moment.Moment; ->moment : () => import("omen").Moment +>moment : () => import("tests/cases/compiler/node_modules/moment/index.d.ts").Moment >moment : any declare namespace moment { @@ -16,7 +16,7 @@ declare namespace moment { } } export = moment; ->moment : () => import("omen").Moment +>moment : () => import("tests/cases/compiler/node_modules/moment/index.d.ts").Moment === tests/cases/compiler/node_modules/moment-timezone/index.d.ts === import * as moment from 'moment'; diff --git a/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.js b/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.js new file mode 100644 index 0000000000000..75086611695c2 --- /dev/null +++ b/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.js @@ -0,0 +1,49 @@ +//// [tests/cases/compiler/reactTransitiveImportHasValidDeclaration.ts] //// + +//// [index.d.ts] +declare namespace React { + export interface DetailedHTMLProps {} + export interface HTMLAttributes {} +} +export = React; +export as namespace React; +//// [index.d.ts] +/// +declare module 'react' { // augment + interface HTMLAttributes { + css?: unknown; + } +} +export interface StyledOtherComponentList { + "div": React.DetailedHTMLProps, HTMLDivElement> +} +export interface StyledOtherComponent {} + +//// [index.d.ts] +export * from "./types/react"; + +//// [index.d.ts] +import {StyledOtherComponent, StyledOtherComponentList} from "create-emotion-styled"; +export default function styled(tag: string): (o: object) => StyledOtherComponent<{}, StyledOtherComponentList["div"], any>; + +//// [index.ts] +import styled from "react-emotion" + +const Form = styled('div')({ color: "red" }) + +export default Form + + +//// [index.js] +"use strict"; +exports.__esModule = true; +var react_emotion_1 = require("react-emotion"); +var Form = react_emotion_1["default"]('div')({ color: "red" }); +exports["default"] = Form; + + +//// [index.d.ts] +/// +/// +declare const Form: import("create-emotion-styled/types/react").StyledOtherComponent<{}, import("react").DetailedHTMLProps, HTMLDivElement>, any>; +export default Form; diff --git a/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.symbols b/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.symbols new file mode 100644 index 0000000000000..aecfd012973c4 --- /dev/null +++ b/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.symbols @@ -0,0 +1,77 @@ +=== tests/cases/compiler/node_modules/react/index.d.ts === +declare namespace React { +>React : Symbol(React, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 0, 0)) + + export interface DetailedHTMLProps {} +>DetailedHTMLProps : Symbol(DetailedHTMLProps, Decl(index.d.ts, 0, 25)) +>T : Symbol(T, Decl(index.d.ts, 1, 39)) +>U : Symbol(U, Decl(index.d.ts, 1, 41)) + + export interface HTMLAttributes {} +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 1, 47), Decl(index.d.ts, 1, 24)) +>T : Symbol(T, Decl(index.d.ts, 2, 36), Decl(index.d.ts, 2, 29)) +} +export = React; +>React : Symbol(React, Decl(index.d.ts, 0, 0)) + +export as namespace React; +>React : Symbol(React, Decl(index.d.ts, 4, 15)) + +=== tests/cases/compiler/node_modules/create-emotion-styled/types/react/index.d.ts === +/// +declare module 'react' { // augment +>'react' : Symbol(React, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 0, 0)) + + interface HTMLAttributes { +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 1, 47), Decl(index.d.ts, 1, 24)) +>T : Symbol(T, Decl(index.d.ts, 2, 36), Decl(index.d.ts, 2, 29)) + + css?: unknown; +>css : Symbol(HTMLAttributes.css, Decl(index.d.ts, 2, 33)) + } +} +export interface StyledOtherComponentList { +>StyledOtherComponentList : Symbol(StyledOtherComponentList, Decl(index.d.ts, 5, 1)) + + "div": React.DetailedHTMLProps, HTMLDivElement> +>"div" : Symbol(StyledOtherComponentList["div"], Decl(index.d.ts, 6, 43)) +>React : Symbol(React, Decl(index.d.ts, 4, 15)) +>DetailedHTMLProps : Symbol(DetailedHTMLProps, Decl(index.d.ts, 0, 25)) +>React : Symbol(React, Decl(index.d.ts, 4, 15)) +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 1, 47), Decl(index.d.ts, 1, 24)) +>HTMLDivElement : Symbol(HTMLDivElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>HTMLDivElement : Symbol(HTMLDivElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +} +export interface StyledOtherComponent {} +>StyledOtherComponent : Symbol(StyledOtherComponent, Decl(index.d.ts, 8, 1)) +>A : Symbol(A, Decl(index.d.ts, 9, 38)) +>B : Symbol(B, Decl(index.d.ts, 9, 40)) +>C : Symbol(C, Decl(index.d.ts, 9, 43)) + +=== tests/cases/compiler/node_modules/create-emotion-styled/index.d.ts === +export * from "./types/react"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/node_modules/react-emotion/index.d.ts === +import {StyledOtherComponent, StyledOtherComponentList} from "create-emotion-styled"; +>StyledOtherComponent : Symbol(StyledOtherComponent, Decl(index.d.ts, 0, 8)) +>StyledOtherComponentList : Symbol(StyledOtherComponentList, Decl(index.d.ts, 0, 29)) + +export default function styled(tag: string): (o: object) => StyledOtherComponent<{}, StyledOtherComponentList["div"], any>; +>styled : Symbol(styled, Decl(index.d.ts, 0, 85)) +>tag : Symbol(tag, Decl(index.d.ts, 1, 31)) +>o : Symbol(o, Decl(index.d.ts, 1, 46)) +>StyledOtherComponent : Symbol(StyledOtherComponent, Decl(index.d.ts, 0, 8)) +>StyledOtherComponentList : Symbol(StyledOtherComponentList, Decl(index.d.ts, 0, 29)) + +=== tests/cases/compiler/index.ts === +import styled from "react-emotion" +>styled : Symbol(styled, Decl(index.ts, 0, 6)) + +const Form = styled('div')({ color: "red" }) +>Form : Symbol(Form, Decl(index.ts, 2, 5)) +>styled : Symbol(styled, Decl(index.ts, 0, 6)) +>color : Symbol(color, Decl(index.ts, 2, 28)) + +export default Form +>Form : Symbol(Form, Decl(index.ts, 2, 5)) + diff --git a/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.types b/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.types new file mode 100644 index 0000000000000..fbaf253a8c594 --- /dev/null +++ b/tests/baselines/reference/reactTransitiveImportHasValidDeclaration.types @@ -0,0 +1,59 @@ +=== tests/cases/compiler/node_modules/react/index.d.ts === +declare namespace React { + export interface DetailedHTMLProps {} + export interface HTMLAttributes {} +} +export = React; +>React : any + +export as namespace React; +>React : any + +=== tests/cases/compiler/node_modules/create-emotion-styled/types/react/index.d.ts === +/// +declare module 'react' { // augment +>'react' : any + + interface HTMLAttributes { + css?: unknown; +>css : unknown + } +} +export interface StyledOtherComponentList { + "div": React.DetailedHTMLProps, HTMLDivElement> +>"div" : import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps, HTMLDivElement> +>React : any +>React : any +} +export interface StyledOtherComponent {} + +=== tests/cases/compiler/node_modules/create-emotion-styled/index.d.ts === +export * from "./types/react"; +No type information for this code. +No type information for this code.=== tests/cases/compiler/node_modules/react-emotion/index.d.ts === +import {StyledOtherComponent, StyledOtherComponentList} from "create-emotion-styled"; +>StyledOtherComponent : any +>StyledOtherComponentList : any + +export default function styled(tag: string): (o: object) => StyledOtherComponent<{}, StyledOtherComponentList["div"], any>; +>styled : (tag: string) => (o: object) => StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps, HTMLDivElement>, any> +>tag : string +>o : object + +=== tests/cases/compiler/index.ts === +import styled from "react-emotion" +>styled : (tag: string) => (o: object) => import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps, HTMLDivElement>, any> + +const Form = styled('div')({ color: "red" }) +>Form : import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps, HTMLDivElement>, any> +>styled('div')({ color: "red" }) : import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps, HTMLDivElement>, any> +>styled('div') : (o: object) => import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps, HTMLDivElement>, any> +>styled : (tag: string) => (o: object) => import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps, HTMLDivElement>, any> +>'div' : "div" +>{ color: "red" } : { color: string; } +>color : string +>"red" : "red" + +export default Form +>Form : import("tests/cases/compiler/node_modules/create-emotion-styled/types/react/index").StyledOtherComponent<{}, import("tests/cases/compiler/node_modules/react/index.d.ts").DetailedHTMLProps, HTMLDivElement>, any> + diff --git a/tests/baselines/reference/umd-augmentation-3.types b/tests/baselines/reference/umd-augmentation-3.types index 8959fadbb25fe..18162921124c4 100644 --- a/tests/baselines/reference/umd-augmentation-3.types +++ b/tests/baselines/reference/umd-augmentation-3.types @@ -46,13 +46,13 @@ var t = p.x; === tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts === export as namespace Math2d; ->Math2d : typeof import("2") +>Math2d : typeof import("tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts") export = M2D; >M2D : typeof M2D declare namespace M2D { ->M2D : typeof import("2") +>M2D : typeof import("tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts") interface Point { x: number; diff --git a/tests/baselines/reference/umd-augmentation-4.types b/tests/baselines/reference/umd-augmentation-4.types index 97c58344c4b80..bb68c080d2ee0 100644 --- a/tests/baselines/reference/umd-augmentation-4.types +++ b/tests/baselines/reference/umd-augmentation-4.types @@ -44,13 +44,13 @@ var t = p.x; === tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts === export as namespace Math2d; ->Math2d : typeof import("2") +>Math2d : typeof import("tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts") export = M2D; >M2D : typeof M2D declare namespace M2D { ->M2D : typeof import("2") +>M2D : typeof import("tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts") interface Point { x: number; diff --git a/tests/cases/compiler/reactTransitiveImportHasValidDeclaration.ts b/tests/cases/compiler/reactTransitiveImportHasValidDeclaration.ts new file mode 100644 index 0000000000000..a11f26305d34b --- /dev/null +++ b/tests/cases/compiler/reactTransitiveImportHasValidDeclaration.ts @@ -0,0 +1,33 @@ +// @declaration: true +// @filename: node_modules/react/index.d.ts +declare namespace React { + export interface DetailedHTMLProps {} + export interface HTMLAttributes {} +} +export = React; +export as namespace React; +// @filename: node_modules/create-emotion-styled/types/react/index.d.ts +/// +declare module 'react' { // augment + interface HTMLAttributes { + css?: unknown; + } +} +export interface StyledOtherComponentList { + "div": React.DetailedHTMLProps, HTMLDivElement> +} +export interface StyledOtherComponent {} + +// @filename: node_modules/create-emotion-styled/index.d.ts +export * from "./types/react"; + +// @filename: node_modules/react-emotion/index.d.ts +import {StyledOtherComponent, StyledOtherComponentList} from "create-emotion-styled"; +export default function styled(tag: string): (o: object) => StyledOtherComponent<{}, StyledOtherComponentList["div"], any>; + +// @filename: index.ts +import styled from "react-emotion" + +const Form = styled('div')({ color: "red" }) + +export default Form From f8237ea49e0b1357f057010342437234f4014e33 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 9 Aug 2018 11:09:48 -0700 Subject: [PATCH 2/2] Use find instead of forEach, remember to also exclude global augmentations --- src/compiler/moduleSpecifiers.ts | 15 ++++----------- src/compiler/utilities.ts | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 451158e2423d2..51835103c52f9 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -232,17 +232,10 @@ namespace ts.moduleSpecifiers { } function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol): string | undefined { - const decl = forEach(moduleSymbol.declarations, d => { - if (!isAmbientModule(d)) return; - if (isExternalModuleAugmentation(d)) { - if (!isExternalModuleNameRelative(getTextOfIdentifierOrLiteral(d.name))) { - return d; - } - return; - } - return d; - }); - if (decl && isModuleDeclaration(decl) && isStringLiteral(decl.name)) { + const decl = find(moduleSymbol.declarations, + d => isNonGlobalAmbientModule(d) && (!isExternalModuleAugmentation(d) || !isExternalModuleNameRelative(getTextOfIdentifierOrLiteral(d.name))) + ) as (ModuleDeclaration & { name: StringLiteral }) | undefined; + if (decl) { return decl.name.text; } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0248b2fd30c9e..95d5d4d03a276 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -639,7 +639,7 @@ namespace ts { } export function getNonAugmentationDeclaration(symbol: Symbol) { - return forEach(symbol.declarations, d => isExternalModuleAugmentation(d) ? undefined : d); + return find(symbol.declarations, d => !isExternalModuleAugmentation(d) && !(isModuleDeclaration(d) && isGlobalScopeAugmentation(d))); } export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) {