Skip to content

Commit 3d2b401

Browse files
authoredOct 28, 2022
Fix assertion functions accessed via wildcard imports (#51324)
* Add test * Resolve alias of property in getTypeOfDottedName * Always resolve * Update tests
1 parent 64d0d5a commit 3d2b401

9 files changed

+380
-1
lines changed
 

‎src/compiler/checker.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -24490,6 +24490,7 @@ namespace ts {
2449024490
}
2449124491

2449224492
function getExplicitTypeOfSymbol(symbol: Symbol, diagnostic?: Diagnostic) {
24493+
symbol = resolveSymbol(symbol);
2449324494
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.ValueModule)) {
2449424495
return getTypeOfSymbol(symbol);
2449524496
}
@@ -24529,7 +24530,7 @@ namespace ts {
2452924530
switch (node.kind) {
2453024531
case SyntaxKind.Identifier:
2453124532
const symbol = getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(node as Identifier));
24532-
return getExplicitTypeOfSymbol(symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol, diagnostic);
24533+
return getExplicitTypeOfSymbol(symbol, diagnostic);
2453324534
case SyntaxKind.ThisKeyword:
2453424535
return getExplicitThisType(node);
2453524536
case SyntaxKind.SuperKeyword:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//// [tests/cases/compiler/assertionFunctionWildcardImport1.ts] ////
2+
3+
//// [ts.ts]
4+
import * as Debug from "../debug";
5+
export { Debug };
6+
7+
//// [debug.ts]
8+
export declare function assert(expression: unknown): asserts expression;
9+
10+
11+
//// [foo.ts]
12+
import * as ts from "./_namespaces/ts";
13+
import { Debug } from "./_namespaces/ts";
14+
15+
ts.Debug.assert(true);
16+
Debug.assert(true);
17+
18+
19+
//// [ts.ts]
20+
export * from "../../core/_namespaces/ts"
21+
22+
23+
//// [bar.ts]
24+
import * as ts from "./_namespaces/ts";
25+
import { Debug } from "./_namespaces/ts";
26+
27+
ts.Debug.assert(true);
28+
Debug.assert(true);
29+
30+
31+
//// [debug.js]
32+
"use strict";
33+
exports.__esModule = true;
34+
//// [ts.js]
35+
"use strict";
36+
exports.__esModule = true;
37+
exports.Debug = void 0;
38+
var Debug = require("../debug");
39+
exports.Debug = Debug;
40+
//// [foo.js]
41+
"use strict";
42+
exports.__esModule = true;
43+
var ts = require("./_namespaces/ts");
44+
var ts_1 = require("./_namespaces/ts");
45+
ts.Debug.assert(true);
46+
ts_1.Debug.assert(true);
47+
//// [ts.js]
48+
"use strict";
49+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
50+
if (k2 === undefined) k2 = k;
51+
var desc = Object.getOwnPropertyDescriptor(m, k);
52+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
53+
desc = { enumerable: true, get: function() { return m[k]; } };
54+
}
55+
Object.defineProperty(o, k2, desc);
56+
}) : (function(o, m, k, k2) {
57+
if (k2 === undefined) k2 = k;
58+
o[k2] = m[k];
59+
}));
60+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
61+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
62+
};
63+
exports.__esModule = true;
64+
__exportStar(require("../../core/_namespaces/ts"), exports);
65+
//// [bar.js]
66+
"use strict";
67+
exports.__esModule = true;
68+
var ts = require("./_namespaces/ts");
69+
var ts_1 = require("./_namespaces/ts");
70+
ts.Debug.assert(true);
71+
ts_1.Debug.assert(true);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
=== tests/cases/compiler/src/core/_namespaces/ts.ts ===
2+
import * as Debug from "../debug";
3+
>Debug : Symbol(Debug, Decl(ts.ts, 0, 6))
4+
5+
export { Debug };
6+
>Debug : Symbol(Debug, Decl(ts.ts, 1, 8))
7+
8+
=== tests/cases/compiler/src/core/debug.ts ===
9+
export declare function assert(expression: unknown): asserts expression;
10+
>assert : Symbol(assert, Decl(debug.ts, 0, 0))
11+
>expression : Symbol(expression, Decl(debug.ts, 0, 31))
12+
>expression : Symbol(expression, Decl(debug.ts, 0, 31))
13+
14+
15+
=== tests/cases/compiler/src/core/foo.ts ===
16+
import * as ts from "./_namespaces/ts";
17+
>ts : Symbol(ts, Decl(foo.ts, 0, 6))
18+
19+
import { Debug } from "./_namespaces/ts";
20+
>Debug : Symbol(Debug, Decl(foo.ts, 1, 8))
21+
22+
ts.Debug.assert(true);
23+
>ts.Debug.assert : Symbol(ts.Debug.assert, Decl(debug.ts, 0, 0))
24+
>ts.Debug : Symbol(ts.Debug, Decl(ts.ts, 1, 8))
25+
>ts : Symbol(ts, Decl(foo.ts, 0, 6))
26+
>Debug : Symbol(ts.Debug, Decl(ts.ts, 1, 8))
27+
>assert : Symbol(ts.Debug.assert, Decl(debug.ts, 0, 0))
28+
29+
Debug.assert(true);
30+
>Debug.assert : Symbol(ts.Debug.assert, Decl(debug.ts, 0, 0))
31+
>Debug : Symbol(Debug, Decl(foo.ts, 1, 8))
32+
>assert : Symbol(ts.Debug.assert, Decl(debug.ts, 0, 0))
33+
34+
35+
=== tests/cases/compiler/src/other/_namespaces/ts.ts ===
36+
37+
export * from "../../core/_namespaces/ts"
38+
39+
40+
=== tests/cases/compiler/src/other/bar.ts ===
41+
import * as ts from "./_namespaces/ts";
42+
>ts : Symbol(ts, Decl(bar.ts, 0, 6))
43+
44+
import { Debug } from "./_namespaces/ts";
45+
>Debug : Symbol(Debug, Decl(bar.ts, 1, 8))
46+
47+
ts.Debug.assert(true);
48+
>ts.Debug.assert : Symbol(Debug.assert, Decl(debug.ts, 0, 0))
49+
>ts.Debug : Symbol(ts.Debug, Decl(ts.ts, 1, 8))
50+
>ts : Symbol(ts, Decl(bar.ts, 0, 6))
51+
>Debug : Symbol(ts.Debug, Decl(ts.ts, 1, 8))
52+
>assert : Symbol(Debug.assert, Decl(debug.ts, 0, 0))
53+
54+
Debug.assert(true);
55+
>Debug.assert : Symbol(Debug.assert, Decl(debug.ts, 0, 0))
56+
>Debug : Symbol(Debug, Decl(bar.ts, 1, 8))
57+
>assert : Symbol(Debug.assert, Decl(debug.ts, 0, 0))
58+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
=== tests/cases/compiler/src/core/_namespaces/ts.ts ===
2+
import * as Debug from "../debug";
3+
>Debug : typeof Debug
4+
5+
export { Debug };
6+
>Debug : typeof Debug
7+
8+
=== tests/cases/compiler/src/core/debug.ts ===
9+
export declare function assert(expression: unknown): asserts expression;
10+
>assert : (expression: unknown) => asserts expression
11+
>expression : unknown
12+
13+
14+
=== tests/cases/compiler/src/core/foo.ts ===
15+
import * as ts from "./_namespaces/ts";
16+
>ts : typeof ts
17+
18+
import { Debug } from "./_namespaces/ts";
19+
>Debug : typeof ts.Debug
20+
21+
ts.Debug.assert(true);
22+
>ts.Debug.assert(true) : void
23+
>ts.Debug.assert : (expression: unknown) => asserts expression
24+
>ts.Debug : typeof ts.Debug
25+
>ts : typeof ts
26+
>Debug : typeof ts.Debug
27+
>assert : (expression: unknown) => asserts expression
28+
>true : true
29+
30+
Debug.assert(true);
31+
>Debug.assert(true) : void
32+
>Debug.assert : (expression: unknown) => asserts expression
33+
>Debug : typeof ts.Debug
34+
>assert : (expression: unknown) => asserts expression
35+
>true : true
36+
37+
38+
=== tests/cases/compiler/src/other/_namespaces/ts.ts ===
39+
40+
export * from "../../core/_namespaces/ts"
41+
42+
43+
=== tests/cases/compiler/src/other/bar.ts ===
44+
import * as ts from "./_namespaces/ts";
45+
>ts : typeof ts
46+
47+
import { Debug } from "./_namespaces/ts";
48+
>Debug : typeof ts.Debug
49+
50+
ts.Debug.assert(true);
51+
>ts.Debug.assert(true) : void
52+
>ts.Debug.assert : (expression: unknown) => asserts expression
53+
>ts.Debug : typeof ts.Debug
54+
>ts : typeof ts
55+
>Debug : typeof ts.Debug
56+
>assert : (expression: unknown) => asserts expression
57+
>true : true
58+
59+
Debug.assert(true);
60+
>Debug.assert(true) : void
61+
>Debug.assert : (expression: unknown) => asserts expression
62+
>Debug : typeof ts.Debug
63+
>assert : (expression: unknown) => asserts expression
64+
>true : true
65+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//// [tests/cases/compiler/assertionFunctionWildcardImport2.ts] ////
2+
3+
//// [asserts.ts]
4+
function isNonNullable<T>(obj: T): asserts obj is NonNullable<T> {
5+
if (obj === undefined || obj === null) {
6+
throw new Error("Must not be a nullable value");
7+
}
8+
}
9+
10+
export {
11+
isNonNullable
12+
};
13+
14+
//// [test.ts]
15+
import * as asserts from "./asserts";
16+
17+
function test(obj: string | null): void {
18+
asserts.isNonNullable(obj);
19+
obj.trim();
20+
}
21+
22+
23+
//// [asserts.js]
24+
"use strict";
25+
exports.__esModule = true;
26+
exports.isNonNullable = void 0;
27+
function isNonNullable(obj) {
28+
if (obj === undefined || obj === null) {
29+
throw new Error("Must not be a nullable value");
30+
}
31+
}
32+
exports.isNonNullable = isNonNullable;
33+
//// [test.js]
34+
"use strict";
35+
exports.__esModule = true;
36+
var asserts = require("./asserts");
37+
function test(obj) {
38+
asserts.isNonNullable(obj);
39+
obj.trim();
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
=== tests/cases/compiler/asserts.ts ===
2+
function isNonNullable<T>(obj: T): asserts obj is NonNullable<T> {
3+
>isNonNullable : Symbol(isNonNullable, Decl(asserts.ts, 0, 0))
4+
>T : Symbol(T, Decl(asserts.ts, 0, 23))
5+
>obj : Symbol(obj, Decl(asserts.ts, 0, 26))
6+
>T : Symbol(T, Decl(asserts.ts, 0, 23))
7+
>obj : Symbol(obj, Decl(asserts.ts, 0, 26))
8+
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
9+
>T : Symbol(T, Decl(asserts.ts, 0, 23))
10+
11+
if (obj === undefined || obj === null) {
12+
>obj : Symbol(obj, Decl(asserts.ts, 0, 26))
13+
>undefined : Symbol(undefined)
14+
>obj : Symbol(obj, Decl(asserts.ts, 0, 26))
15+
16+
throw new Error("Must not be a nullable value");
17+
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
18+
}
19+
}
20+
21+
export {
22+
isNonNullable
23+
>isNonNullable : Symbol(isNonNullable, Decl(asserts.ts, 6, 8))
24+
25+
};
26+
27+
=== tests/cases/compiler/test.ts ===
28+
import * as asserts from "./asserts";
29+
>asserts : Symbol(asserts, Decl(test.ts, 0, 6))
30+
31+
function test(obj: string | null): void {
32+
>test : Symbol(test, Decl(test.ts, 0, 37))
33+
>obj : Symbol(obj, Decl(test.ts, 2, 14))
34+
35+
asserts.isNonNullable(obj);
36+
>asserts.isNonNullable : Symbol(asserts.isNonNullable, Decl(asserts.ts, 6, 8))
37+
>asserts : Symbol(asserts, Decl(test.ts, 0, 6))
38+
>isNonNullable : Symbol(asserts.isNonNullable, Decl(asserts.ts, 6, 8))
39+
>obj : Symbol(obj, Decl(test.ts, 2, 14))
40+
41+
obj.trim();
42+
>obj.trim : Symbol(String.trim, Decl(lib.es5.d.ts, --, --))
43+
>obj : Symbol(obj, Decl(test.ts, 2, 14))
44+
>trim : Symbol(String.trim, Decl(lib.es5.d.ts, --, --))
45+
}
46+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
=== tests/cases/compiler/asserts.ts ===
2+
function isNonNullable<T>(obj: T): asserts obj is NonNullable<T> {
3+
>isNonNullable : <T>(obj: T) => asserts obj is NonNullable<T>
4+
>obj : T
5+
6+
if (obj === undefined || obj === null) {
7+
>obj === undefined || obj === null : boolean
8+
>obj === undefined : boolean
9+
>obj : T
10+
>undefined : undefined
11+
>obj === null : boolean
12+
>obj : T & ({} | null)
13+
>null : null
14+
15+
throw new Error("Must not be a nullable value");
16+
>new Error("Must not be a nullable value") : Error
17+
>Error : ErrorConstructor
18+
>"Must not be a nullable value" : "Must not be a nullable value"
19+
}
20+
}
21+
22+
export {
23+
isNonNullable
24+
>isNonNullable : <T>(obj: T) => asserts obj is NonNullable<T>
25+
26+
};
27+
28+
=== tests/cases/compiler/test.ts ===
29+
import * as asserts from "./asserts";
30+
>asserts : typeof asserts
31+
32+
function test(obj: string | null): void {
33+
>test : (obj: string | null) => void
34+
>obj : string | null
35+
>null : null
36+
37+
asserts.isNonNullable(obj);
38+
>asserts.isNonNullable(obj) : void
39+
>asserts.isNonNullable : <T>(obj: T) => asserts obj is NonNullable<T>
40+
>asserts : typeof asserts
41+
>isNonNullable : <T>(obj: T) => asserts obj is NonNullable<T>
42+
>obj : string | null
43+
44+
obj.trim();
45+
>obj.trim() : string
46+
>obj.trim : () => string
47+
>obj : string
48+
>trim : () => string
49+
}
50+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// @strict: true
2+
3+
// @filename: src/core/_namespaces/ts.ts
4+
import * as Debug from "../debug";
5+
export { Debug };
6+
7+
// @filename: src/core/debug.ts
8+
export declare function assert(expression: unknown): asserts expression;
9+
10+
11+
// @filename: src/core/foo.ts
12+
import * as ts from "./_namespaces/ts";
13+
import { Debug } from "./_namespaces/ts";
14+
15+
ts.Debug.assert(true);
16+
Debug.assert(true);
17+
18+
19+
// @filename: src/other/_namespaces/ts.ts
20+
export * from "../../core/_namespaces/ts"
21+
22+
23+
// @filename: src/other/bar.ts
24+
import * as ts from "./_namespaces/ts";
25+
import { Debug } from "./_namespaces/ts";
26+
27+
ts.Debug.assert(true);
28+
Debug.assert(true);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// @strict: true
2+
3+
// @filename: asserts.ts
4+
function isNonNullable<T>(obj: T): asserts obj is NonNullable<T> {
5+
if (obj === undefined || obj === null) {
6+
throw new Error("Must not be a nullable value");
7+
}
8+
}
9+
10+
export {
11+
isNonNullable
12+
};
13+
14+
// @filename: test.ts
15+
import * as asserts from "./asserts";
16+
17+
function test(obj: string | null): void {
18+
asserts.isNonNullable(obj);
19+
obj.trim();
20+
}

0 commit comments

Comments
 (0)
Please sign in to comment.