Skip to content

Commit e96c10f

Browse files
authored
fix(26635): allow casts only when JSDoc type directly attached to an expression (microsoft#45960)
1 parent 061f02c commit e96c10f

File tree

6 files changed

+153
-1
lines changed

6 files changed

+153
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33722,7 +33722,7 @@ namespace ts {
3372233722
}
3372333723

3372433724
function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
33725-
if (isJSDocTypeAssertion(node)) {
33725+
if (hasJSDocNodes(node) && isJSDocTypeAssertion(node)) {
3372633726
const type = getJSDocTypeAssertionType(node);
3372733727
return checkAssertionWorker(type, type, node.expression, checkMode);
3372833728
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
tests/cases/compiler/jsdocTypeCast.js(6,9): error TS2322: Type 'string' is not assignable to type '"a" | "b"'.
2+
tests/cases/compiler/jsdocTypeCast.js(10,9): error TS2322: Type 'string' is not assignable to type '"a" | "b"'.
3+
4+
5+
==== tests/cases/compiler/jsdocTypeCast.js (2 errors) ====
6+
/**
7+
* @param {string} x
8+
*/
9+
function f(x) {
10+
/** @type {'a' | 'b'} */
11+
let a = (x); // Error
12+
~
13+
!!! error TS2322: Type 'string' is not assignable to type '"a" | "b"'.
14+
a;
15+
16+
/** @type {'a' | 'b'} */
17+
let b = (((x))); // Error
18+
~
19+
!!! error TS2322: Type 'string' is not assignable to type '"a" | "b"'.
20+
b;
21+
22+
/** @type {'a' | 'b'} */
23+
let c = /** @type {'a' | 'b'} */ (x); // Ok
24+
c;
25+
}
26+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//// [jsdocTypeCast.js]
2+
/**
3+
* @param {string} x
4+
*/
5+
function f(x) {
6+
/** @type {'a' | 'b'} */
7+
let a = (x); // Error
8+
a;
9+
10+
/** @type {'a' | 'b'} */
11+
let b = (((x))); // Error
12+
b;
13+
14+
/** @type {'a' | 'b'} */
15+
let c = /** @type {'a' | 'b'} */ (x); // Ok
16+
c;
17+
}
18+
19+
20+
//// [jsdocTypeCast.js]
21+
/**
22+
* @param {string} x
23+
*/
24+
function f(x) {
25+
/** @type {'a' | 'b'} */
26+
var a = (x); // Error
27+
a;
28+
/** @type {'a' | 'b'} */
29+
var b = (((x))); // Error
30+
b;
31+
/** @type {'a' | 'b'} */
32+
var c = /** @type {'a' | 'b'} */ (x); // Ok
33+
c;
34+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/compiler/jsdocTypeCast.js ===
2+
/**
3+
* @param {string} x
4+
*/
5+
function f(x) {
6+
>f : Symbol(f, Decl(jsdocTypeCast.js, 0, 0))
7+
>x : Symbol(x, Decl(jsdocTypeCast.js, 3, 12))
8+
9+
/** @type {'a' | 'b'} */
10+
let a = (x); // Error
11+
>a : Symbol(a, Decl(jsdocTypeCast.js, 5, 7))
12+
>x : Symbol(x, Decl(jsdocTypeCast.js, 3, 12))
13+
14+
a;
15+
>a : Symbol(a, Decl(jsdocTypeCast.js, 5, 7))
16+
17+
/** @type {'a' | 'b'} */
18+
let b = (((x))); // Error
19+
>b : Symbol(b, Decl(jsdocTypeCast.js, 9, 7))
20+
>x : Symbol(x, Decl(jsdocTypeCast.js, 3, 12))
21+
22+
b;
23+
>b : Symbol(b, Decl(jsdocTypeCast.js, 9, 7))
24+
25+
/** @type {'a' | 'b'} */
26+
let c = /** @type {'a' | 'b'} */ (x); // Ok
27+
>c : Symbol(c, Decl(jsdocTypeCast.js, 13, 7))
28+
>x : Symbol(x, Decl(jsdocTypeCast.js, 3, 12))
29+
30+
c;
31+
>c : Symbol(c, Decl(jsdocTypeCast.js, 13, 7))
32+
}
33+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
=== tests/cases/compiler/jsdocTypeCast.js ===
2+
/**
3+
* @param {string} x
4+
*/
5+
function f(x) {
6+
>f : (x: string) => void
7+
>x : string
8+
9+
/** @type {'a' | 'b'} */
10+
let a = (x); // Error
11+
>a : "a" | "b"
12+
>(x) : "a" | "b"
13+
>x : string
14+
15+
a;
16+
>a : "a" | "b"
17+
18+
/** @type {'a' | 'b'} */
19+
let b = (((x))); // Error
20+
>b : "a" | "b"
21+
>(((x))) : "a" | "b"
22+
>((x)) : string
23+
>(x) : string
24+
>x : string
25+
26+
b;
27+
>b : "a" | "b"
28+
29+
/** @type {'a' | 'b'} */
30+
let c = /** @type {'a' | 'b'} */ (x); // Ok
31+
>c : "a" | "b"
32+
>(x) : "a" | "b"
33+
>x : string
34+
35+
c;
36+
>c : "a" | "b"
37+
}
38+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @outDir: ./out
4+
// @filename: jsdocTypeCast.js
5+
6+
/**
7+
* @param {string} x
8+
*/
9+
function f(x) {
10+
/** @type {'a' | 'b'} */
11+
let a = (x); // Error
12+
a;
13+
14+
/** @type {'a' | 'b'} */
15+
let b = (((x))); // Error
16+
b;
17+
18+
/** @type {'a' | 'b'} */
19+
let c = /** @type {'a' | 'b'} */ (x); // Ok
20+
c;
21+
}

0 commit comments

Comments
 (0)