Skip to content

Commit 1785d6c

Browse files
authored
Special-case export assigned namespaces in getSpecifierForModuleSymbol so they behave like their containing module symbol (#38151)
1 parent fe140ac commit 1785d6c

5 files changed

+264
-4
lines changed

src/compiler/checker.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3517,12 +3517,16 @@ namespace ts {
35173517
return mapDefined(candidates, candidate => getAliasForSymbolInContainer(candidate, symbol) ? candidate : undefined);
35183518

35193519
function fileSymbolIfFileSymbolExportEqualsContainer(d: Declaration) {
3520-
const fileSymbol = getExternalModuleContainer(d);
3521-
const exported = fileSymbol && fileSymbol.exports && fileSymbol.exports.get(InternalSymbolName.ExportEquals);
3522-
return exported && container && getSymbolIfSameReference(exported, container) ? fileSymbol : undefined;
3520+
return container && getFileSymbolIfFileSymbolExportEqualsContainer(d, container);
35233521
}
35243522
}
35253523

3524+
function getFileSymbolIfFileSymbolExportEqualsContainer(d: Declaration, container: Symbol) {
3525+
const fileSymbol = getExternalModuleContainer(d);
3526+
const exported = fileSymbol && fileSymbol.exports && fileSymbol.exports.get(InternalSymbolName.ExportEquals);
3527+
return exported && getSymbolIfSameReference(exported, container) ? fileSymbol : undefined;
3528+
}
3529+
35263530
function getAliasForSymbolInContainer(container: Symbol, symbol: Symbol) {
35273531
if (container === getParentOfSymbol(symbol)) {
35283532
// fast path, `symbol` is either already the alias or isn't aliased
@@ -5138,7 +5142,13 @@ namespace ts {
51385142
}
51395143

51405144
function getSpecifierForModuleSymbol(symbol: Symbol, context: NodeBuilderContext) {
5141-
const file = getDeclarationOfKind<SourceFile>(symbol, SyntaxKind.SourceFile);
5145+
let file = getDeclarationOfKind<SourceFile>(symbol, SyntaxKind.SourceFile);
5146+
if (!file) {
5147+
const equivalentFileSymbol = firstDefined(symbol.declarations, d => getFileSymbolIfFileSymbolExportEqualsContainer(d, symbol));
5148+
if (equivalentFileSymbol) {
5149+
file = getDeclarationOfKind<SourceFile>(equivalentFileSymbol, SyntaxKind.SourceFile);
5150+
}
5151+
}
51425152
if (file && file.moduleName !== undefined) {
51435153
// Use the amd name if it is available
51445154
return file.moduleName;
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//// [tests/cases/compiler/declarationEmitExportAssignedNamespaceNoTripleSlashTypesReference.ts] ////
2+
3+
//// [index.d.ts]
4+
export = React;
5+
6+
declare namespace React {
7+
export type Component<T = any, U = {}, V = {}> = { x: T, y: U, z: V };
8+
export interface DOMAttributes<T> { }
9+
}
10+
//// [index.d.ts]
11+
import {
12+
Component
13+
} from 'react'
14+
export {};
15+
16+
declare module 'react' {
17+
interface DOMAttributes<T> {
18+
css?: any
19+
}
20+
}
21+
22+
//// [get-comp.ts]
23+
import {Component} from 'react';
24+
25+
export function getComp(): Component {
26+
return {} as any as Component
27+
}
28+
//// [inferred-comp-export.ts]
29+
import { getComp } from "./get-comp";
30+
31+
// this shouldn't need any triple-slash references - it should have a direct import to `react` and that's it
32+
// This issue (#35343) _only_ reproduces in the test harness when the file in question is in a subfolder
33+
export const obj = {
34+
comp: getComp()
35+
}
36+
//// [some-other-file.ts]
37+
export * from '@emotion/core';
38+
39+
40+
//// [get-comp.js]
41+
"use strict";
42+
exports.__esModule = true;
43+
exports.getComp = void 0;
44+
function getComp() {
45+
return {};
46+
}
47+
exports.getComp = getComp;
48+
//// [inferred-comp-export.js]
49+
"use strict";
50+
exports.__esModule = true;
51+
exports.obj = void 0;
52+
var get_comp_1 = require("./get-comp");
53+
// this shouldn't need any triple-slash references - it should have a direct import to `react` and that's it
54+
// This issue (#35343) _only_ reproduces in the test harness when the file in question is in a subfolder
55+
exports.obj = {
56+
comp: get_comp_1.getComp()
57+
};
58+
//// [some-other-file.js]
59+
"use strict";
60+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
61+
if (k2 === undefined) k2 = k;
62+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
63+
}) : (function(o, m, k, k2) {
64+
if (k2 === undefined) k2 = k;
65+
o[k2] = m[k];
66+
}));
67+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
68+
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
69+
}
70+
exports.__esModule = true;
71+
__exportStar(require("@emotion/core"), exports);
72+
73+
74+
//// [get-comp.d.ts]
75+
import { Component } from 'react';
76+
export declare function getComp(): Component;
77+
//// [inferred-comp-export.d.ts]
78+
export declare const obj: {
79+
comp: import("react").Component<any, {}, {}>;
80+
};
81+
//// [some-other-file.d.ts]
82+
export * from '@emotion/core';
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
=== tests/cases/compiler/node_modules/@types/react/index.d.ts ===
2+
export = React;
3+
>React : Symbol(React, Decl(index.d.ts, 0, 15), Decl(index.d.ts, 3, 10))
4+
5+
declare namespace React {
6+
>React : Symbol(React, Decl(index.d.ts, 0, 15), Decl(index.d.ts, 3, 10))
7+
8+
export type Component<T = any, U = {}, V = {}> = { x: T, y: U, z: V };
9+
>Component : Symbol(Component, Decl(index.d.ts, 2, 25))
10+
>T : Symbol(T, Decl(index.d.ts, 3, 26))
11+
>U : Symbol(U, Decl(index.d.ts, 3, 34))
12+
>V : Symbol(V, Decl(index.d.ts, 3, 42))
13+
>x : Symbol(x, Decl(index.d.ts, 3, 54))
14+
>T : Symbol(T, Decl(index.d.ts, 3, 26))
15+
>y : Symbol(y, Decl(index.d.ts, 3, 60))
16+
>U : Symbol(U, Decl(index.d.ts, 3, 34))
17+
>z : Symbol(z, Decl(index.d.ts, 3, 66))
18+
>V : Symbol(V, Decl(index.d.ts, 3, 42))
19+
20+
export interface DOMAttributes<T> { }
21+
>DOMAttributes : Symbol(DOMAttributes, Decl(index.d.ts, 3, 74), Decl(index.d.ts, 5, 24))
22+
>T : Symbol(T, Decl(index.d.ts, 4, 35), Decl(index.d.ts, 6, 28))
23+
}
24+
=== tests/cases/compiler/node_modules/@emotion/core/index.d.ts ===
25+
import {
26+
Component
27+
>Component : Symbol(Component, Decl(index.d.ts, 0, 8))
28+
29+
} from 'react'
30+
export {};
31+
32+
declare module 'react' {
33+
>'react' : Symbol(React, Decl(index.d.ts, 0, 15), Decl(index.d.ts, 3, 10))
34+
35+
interface DOMAttributes<T> {
36+
>DOMAttributes : Symbol(DOMAttributes, Decl(index.d.ts, 3, 74), Decl(index.d.ts, 5, 24))
37+
>T : Symbol(T, Decl(index.d.ts, 4, 35), Decl(index.d.ts, 6, 28))
38+
39+
css?: any
40+
>css : Symbol(DOMAttributes.css, Decl(index.d.ts, 6, 32))
41+
}
42+
}
43+
44+
=== tests/cases/compiler/src/get-comp.ts ===
45+
import {Component} from 'react';
46+
>Component : Symbol(Component, Decl(get-comp.ts, 0, 8))
47+
48+
export function getComp(): Component {
49+
>getComp : Symbol(getComp, Decl(get-comp.ts, 0, 32))
50+
>Component : Symbol(Component, Decl(get-comp.ts, 0, 8))
51+
52+
return {} as any as Component
53+
>Component : Symbol(Component, Decl(get-comp.ts, 0, 8))
54+
}
55+
=== tests/cases/compiler/src/inferred-comp-export.ts ===
56+
import { getComp } from "./get-comp";
57+
>getComp : Symbol(getComp, Decl(inferred-comp-export.ts, 0, 8))
58+
59+
// this shouldn't need any triple-slash references - it should have a direct import to `react` and that's it
60+
// This issue (#35343) _only_ reproduces in the test harness when the file in question is in a subfolder
61+
export const obj = {
62+
>obj : Symbol(obj, Decl(inferred-comp-export.ts, 4, 12))
63+
64+
comp: getComp()
65+
>comp : Symbol(comp, Decl(inferred-comp-export.ts, 4, 20))
66+
>getComp : Symbol(getComp, Decl(inferred-comp-export.ts, 0, 8))
67+
}
68+
=== tests/cases/compiler/src/some-other-file.ts ===
69+
export * from '@emotion/core';
70+
No type information for this code.
71+
No type information for this code.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
=== tests/cases/compiler/node_modules/@types/react/index.d.ts ===
2+
export = React;
3+
>React : any
4+
5+
declare namespace React {
6+
export type Component<T = any, U = {}, V = {}> = { x: T, y: U, z: V };
7+
>Component : Component<T, U, V>
8+
>x : T
9+
>y : U
10+
>z : V
11+
12+
export interface DOMAttributes<T> { }
13+
}
14+
=== tests/cases/compiler/node_modules/@emotion/core/index.d.ts ===
15+
import {
16+
Component
17+
>Component : any
18+
19+
} from 'react'
20+
export {};
21+
22+
declare module 'react' {
23+
>'react' : error
24+
25+
interface DOMAttributes<T> {
26+
css?: any
27+
>css : any
28+
}
29+
}
30+
31+
=== tests/cases/compiler/src/get-comp.ts ===
32+
import {Component} from 'react';
33+
>Component : any
34+
35+
export function getComp(): Component {
36+
>getComp : () => Component
37+
38+
return {} as any as Component
39+
>{} as any as Component : Component<any, {}, {}>
40+
>{} as any : any
41+
>{} : {}
42+
}
43+
=== tests/cases/compiler/src/inferred-comp-export.ts ===
44+
import { getComp } from "./get-comp";
45+
>getComp : () => import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>
46+
47+
// this shouldn't need any triple-slash references - it should have a direct import to `react` and that's it
48+
// This issue (#35343) _only_ reproduces in the test harness when the file in question is in a subfolder
49+
export const obj = {
50+
>obj : { comp: import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>; }
51+
>{ comp: getComp()} : { comp: import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>; }
52+
53+
comp: getComp()
54+
>comp : import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>
55+
>getComp() : import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>
56+
>getComp : () => import("tests/cases/compiler/node_modules/@types/react/index").Component<any, {}, {}>
57+
}
58+
=== tests/cases/compiler/src/some-other-file.ts ===
59+
export * from '@emotion/core';
60+
No type information for this code.
61+
No type information for this code.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// @declaration: true
2+
// @filename: node_modules/@types/react/index.d.ts
3+
export = React;
4+
5+
declare namespace React {
6+
export type Component<T = any, U = {}, V = {}> = { x: T, y: U, z: V };
7+
export interface DOMAttributes<T> { }
8+
}
9+
// @filename: node_modules/@emotion/core/index.d.ts
10+
import {
11+
Component
12+
} from 'react'
13+
export {};
14+
15+
declare module 'react' {
16+
interface DOMAttributes<T> {
17+
css?: any
18+
}
19+
}
20+
21+
// @filename: src/get-comp.ts
22+
import {Component} from 'react';
23+
24+
export function getComp(): Component {
25+
return {} as any as Component
26+
}
27+
// @filename: src/inferred-comp-export.ts
28+
import { getComp } from "./get-comp";
29+
30+
// this shouldn't need any triple-slash references - it should have a direct import to `react` and that's it
31+
// This issue (#35343) _only_ reproduces in the test harness when the file in question is in a subfolder
32+
export const obj = {
33+
comp: getComp()
34+
}
35+
// @filename: src/some-other-file.ts
36+
export * from '@emotion/core';

0 commit comments

Comments
 (0)