Skip to content

Commit b3be052

Browse files
committed
fix(45233): allow type assertion in ExportAssignment with JSDoc type definition
1 parent 1f85123 commit b3be052

16 files changed

+289
-1
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38841,11 +38841,17 @@ namespace ts {
3884138841
if (!checkGrammarDecoratorsAndModifiers(node) && hasEffectiveModifiers(node)) {
3884238842
grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers);
3884338843
}
38844+
38845+
const typeTag = isInJSFile(node) ? getJSDocTypeTag(node) : undefined;
38846+
if (typeTag) {
38847+
checkAssertionWorker(typeTag.typeExpression.type, typeTag.typeExpression.type, node.expression);
38848+
return;
38849+
}
38850+
3884438851
if (node.expression.kind === SyntaxKind.Identifier) {
3884538852
const id = node.expression as Identifier;
3884638853
const sym = resolveEntityName(id, SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, node);
3884738854
if (sym) {
38848-
3884938855
markAliasReferenced(sym, id);
3885038856
// If not a value, we're interpreting the identifier as a type export, along the lines of (`export { Id as default }`)
3885138857
const target = sym.flags & SymbolFlags.Alias ? resolveAlias(sym) : sym;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
tests/cases/compiler/a.js(7,12): error TS2352: Conversion of type '{ c: boolean; }' to type 'Foo' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
2+
Type '{ c: boolean; }' is missing the following properties from type 'Foo': a, b
3+
4+
5+
==== tests/cases/compiler/checkJsdocTypeTagOnExportAssignment1.js (0 errors) ====
6+
7+
==== tests/cases/compiler/a.js (1 errors) ====
8+
/**
9+
* @typedef {Object} Foo
10+
* @property {boolean} a
11+
* @property {boolean} b
12+
*/
13+
14+
/** @type {Foo} */
15+
~~~
16+
!!! error TS2352: Conversion of type '{ c: boolean; }' to type 'Foo' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
17+
!!! error TS2352: Type '{ c: boolean; }' is missing the following properties from type 'Foo': a, b
18+
export default { c: false };
19+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//// [tests/cases/compiler/checkJsdocTypeTagOnExportAssignment1.ts] ////
2+
3+
//// [checkJsdocTypeTagOnExportAssignment1.js]
4+
5+
//// [a.js]
6+
/**
7+
* @typedef {Object} Foo
8+
* @property {boolean} a
9+
* @property {boolean} b
10+
*/
11+
12+
/** @type {Foo} */
13+
export default { c: false };
14+
15+
16+
//// [checkJsdocTypeTagOnExportAssignment1.js]
17+
//// [a.js]
18+
"use strict";
19+
/**
20+
* @typedef {Object} Foo
21+
* @property {boolean} a
22+
* @property {boolean} b
23+
*/
24+
exports.__esModule = true;
25+
/** @type {Foo} */
26+
exports["default"] = { c: false };
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
=== tests/cases/compiler/checkJsdocTypeTagOnExportAssignment1.js ===
2+
3+
No type information for this code.=== tests/cases/compiler/a.js ===
4+
/**
5+
* @typedef {Object} Foo
6+
* @property {boolean} a
7+
* @property {boolean} b
8+
*/
9+
10+
/** @type {Foo} */
11+
export default { c: false };
12+
>c : Symbol(c, Decl(a.js, 7, 16))
13+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
=== tests/cases/compiler/checkJsdocTypeTagOnExportAssignment1.js ===
2+
3+
No type information for this code.=== tests/cases/compiler/a.js ===
4+
/**
5+
* @typedef {Object} Foo
6+
* @property {boolean} a
7+
* @property {boolean} b
8+
*/
9+
10+
/** @type {Foo} */
11+
export default { c: false };
12+
>{ c: false } : { c: boolean; }
13+
>c : boolean
14+
>false : false
15+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
tests/cases/compiler/b.js(1,12): error TS2352: Conversion of type '{ c: boolean; }' to type 'Foo' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
2+
Type '{ c: boolean; }' is missing the following properties from type 'Foo': a, b
3+
4+
5+
==== tests/cases/compiler/checkJsdocTypeTagOnExportAssignment2.js (0 errors) ====
6+
7+
==== tests/cases/compiler/a.ts (0 errors) ====
8+
export interface Foo {
9+
a: number;
10+
b: number;
11+
}
12+
13+
==== tests/cases/compiler/b.js (1 errors) ====
14+
/** @type {import("./a").Foo} */
15+
~~~~~~~~~~~~~~~~~
16+
!!! error TS2352: Conversion of type '{ c: boolean; }' to type 'Foo' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
17+
!!! error TS2352: Type '{ c: boolean; }' is missing the following properties from type 'Foo': a, b
18+
export default { c: false };
19+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//// [tests/cases/compiler/checkJsdocTypeTagOnExportAssignment2.ts] ////
2+
3+
//// [checkJsdocTypeTagOnExportAssignment2.js]
4+
5+
//// [a.ts]
6+
export interface Foo {
7+
a: number;
8+
b: number;
9+
}
10+
11+
//// [b.js]
12+
/** @type {import("./a").Foo} */
13+
export default { c: false };
14+
15+
16+
//// [checkJsdocTypeTagOnExportAssignment2.js]
17+
//// [a.js]
18+
"use strict";
19+
exports.__esModule = true;
20+
//// [b.js]
21+
"use strict";
22+
exports.__esModule = true;
23+
/** @type {import("./a").Foo} */
24+
exports["default"] = { c: false };
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
=== tests/cases/compiler/checkJsdocTypeTagOnExportAssignment2.js ===
2+
3+
No type information for this code.=== tests/cases/compiler/a.ts ===
4+
export interface Foo {
5+
>Foo : Symbol(Foo, Decl(a.ts, 0, 0))
6+
7+
a: number;
8+
>a : Symbol(Foo.a, Decl(a.ts, 0, 22))
9+
10+
b: number;
11+
>b : Symbol(Foo.b, Decl(a.ts, 1, 14))
12+
}
13+
14+
=== tests/cases/compiler/b.js ===
15+
/** @type {import("./a").Foo} */
16+
export default { c: false };
17+
>c : Symbol(c, Decl(b.js, 1, 16))
18+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
=== tests/cases/compiler/checkJsdocTypeTagOnExportAssignment2.js ===
2+
3+
No type information for this code.=== tests/cases/compiler/a.ts ===
4+
export interface Foo {
5+
a: number;
6+
>a : number
7+
8+
b: number;
9+
>b : number
10+
}
11+
12+
=== tests/cases/compiler/b.js ===
13+
/** @type {import("./a").Foo} */
14+
export default { c: false };
15+
>{ c: false } : { c: boolean; }
16+
>c : boolean
17+
>false : false
18+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
tests/cases/compiler/a.js(9,12): error TS2352: Conversion of type '{ c: number; }' to type 'Foo' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
2+
Type '{ c: number; }' is missing the following properties from type 'Foo': a, b
3+
4+
5+
==== tests/cases/compiler/checkJsdocTypeTagOnExportAssignment3.js (0 errors) ====
6+
7+
==== tests/cases/compiler/a.js (1 errors) ====
8+
/**
9+
* @typedef {Object} Foo
10+
* @property {boolean} a
11+
* @property {boolean} b
12+
*/
13+
14+
const bar = { c: 1 };
15+
16+
/** @type {Foo} */
17+
~~~
18+
!!! error TS2352: Conversion of type '{ c: number; }' to type 'Foo' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
19+
!!! error TS2352: Type '{ c: number; }' is missing the following properties from type 'Foo': a, b
20+
export default bar;
21+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//// [tests/cases/compiler/checkJsdocTypeTagOnExportAssignment3.ts] ////
2+
3+
//// [checkJsdocTypeTagOnExportAssignment3.js]
4+
5+
//// [a.js]
6+
/**
7+
* @typedef {Object} Foo
8+
* @property {boolean} a
9+
* @property {boolean} b
10+
*/
11+
12+
const bar = { c: 1 };
13+
14+
/** @type {Foo} */
15+
export default bar;
16+
17+
18+
//// [checkJsdocTypeTagOnExportAssignment3.js]
19+
//// [a.js]
20+
"use strict";
21+
/**
22+
* @typedef {Object} Foo
23+
* @property {boolean} a
24+
* @property {boolean} b
25+
*/
26+
exports.__esModule = true;
27+
var bar = { c: 1 };
28+
/** @type {Foo} */
29+
exports["default"] = bar;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/compiler/checkJsdocTypeTagOnExportAssignment3.js ===
2+
3+
No type information for this code.=== tests/cases/compiler/a.js ===
4+
/**
5+
* @typedef {Object} Foo
6+
* @property {boolean} a
7+
* @property {boolean} b
8+
*/
9+
10+
const bar = { c: 1 };
11+
>bar : Symbol(bar, Decl(a.js, 6, 5))
12+
>c : Symbol(c, Decl(a.js, 6, 13))
13+
14+
/** @type {Foo} */
15+
export default bar;
16+
>bar : Symbol(bar, Decl(a.js, 6, 5))
17+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
=== tests/cases/compiler/checkJsdocTypeTagOnExportAssignment3.js ===
2+
3+
No type information for this code.=== tests/cases/compiler/a.js ===
4+
/**
5+
* @typedef {Object} Foo
6+
* @property {boolean} a
7+
* @property {boolean} b
8+
*/
9+
10+
const bar = { c: 1 };
11+
>bar : { c: number; }
12+
>{ c: 1 } : { c: number; }
13+
>c : number
14+
>1 : 1
15+
16+
/** @type {Foo} */
17+
export default bar;
18+
>bar : { c: number; }
19+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @outDir: ./out
4+
// @filename: checkJsdocTypeTagOnExportAssignment1.js
5+
6+
// @Filename: a.js
7+
/**
8+
* @typedef {Object} Foo
9+
* @property {boolean} a
10+
* @property {boolean} b
11+
*/
12+
13+
/** @type {Foo} */
14+
export default { c: false };
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @outDir: ./out
4+
// @filename: checkJsdocTypeTagOnExportAssignment2.js
5+
6+
// @Filename: a.ts
7+
export interface Foo {
8+
a: number;
9+
b: number;
10+
}
11+
12+
// @Filename: b.js
13+
/** @type {import("./a").Foo} */
14+
export default { c: false };
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @outDir: ./out
4+
// @filename: checkJsdocTypeTagOnExportAssignment3.js
5+
6+
// @Filename: a.js
7+
/**
8+
* @typedef {Object} Foo
9+
* @property {boolean} a
10+
* @property {boolean} b
11+
*/
12+
13+
const bar = { c: 1 };
14+
15+
/** @type {Foo} */
16+
export default bar;

0 commit comments

Comments
 (0)