fix(26635): allow casts only when JSDoc type directly attached to an expression (#45960)

This commit is contained in:
Oleksandr T 2021-09-29 22:16:27 +03:00 committed by GitHub
parent 061f02cd64
commit e96c10fe0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 153 additions and 1 deletions

View File

@ -33722,7 +33722,7 @@ namespace ts {
}
function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
if (isJSDocTypeAssertion(node)) {
if (hasJSDocNodes(node) && isJSDocTypeAssertion(node)) {
const type = getJSDocTypeAssertionType(node);
return checkAssertionWorker(type, type, node.expression, checkMode);
}

View File

@ -0,0 +1,26 @@
tests/cases/compiler/jsdocTypeCast.js(6,9): error TS2322: Type 'string' is not assignable to type '"a" | "b"'.
tests/cases/compiler/jsdocTypeCast.js(10,9): error TS2322: Type 'string' is not assignable to type '"a" | "b"'.
==== tests/cases/compiler/jsdocTypeCast.js (2 errors) ====
/**
* @param {string} x
*/
function f(x) {
/** @type {'a' | 'b'} */
let a = (x); // Error
~
!!! error TS2322: Type 'string' is not assignable to type '"a" | "b"'.
a;
/** @type {'a' | 'b'} */
let b = (((x))); // Error
~
!!! error TS2322: Type 'string' is not assignable to type '"a" | "b"'.
b;
/** @type {'a' | 'b'} */
let c = /** @type {'a' | 'b'} */ (x); // Ok
c;
}

View File

@ -0,0 +1,34 @@
//// [jsdocTypeCast.js]
/**
* @param {string} x
*/
function f(x) {
/** @type {'a' | 'b'} */
let a = (x); // Error
a;
/** @type {'a' | 'b'} */
let b = (((x))); // Error
b;
/** @type {'a' | 'b'} */
let c = /** @type {'a' | 'b'} */ (x); // Ok
c;
}
//// [jsdocTypeCast.js]
/**
* @param {string} x
*/
function f(x) {
/** @type {'a' | 'b'} */
var a = (x); // Error
a;
/** @type {'a' | 'b'} */
var b = (((x))); // Error
b;
/** @type {'a' | 'b'} */
var c = /** @type {'a' | 'b'} */ (x); // Ok
c;
}

View File

@ -0,0 +1,33 @@
=== tests/cases/compiler/jsdocTypeCast.js ===
/**
* @param {string} x
*/
function f(x) {
>f : Symbol(f, Decl(jsdocTypeCast.js, 0, 0))
>x : Symbol(x, Decl(jsdocTypeCast.js, 3, 12))
/** @type {'a' | 'b'} */
let a = (x); // Error
>a : Symbol(a, Decl(jsdocTypeCast.js, 5, 7))
>x : Symbol(x, Decl(jsdocTypeCast.js, 3, 12))
a;
>a : Symbol(a, Decl(jsdocTypeCast.js, 5, 7))
/** @type {'a' | 'b'} */
let b = (((x))); // Error
>b : Symbol(b, Decl(jsdocTypeCast.js, 9, 7))
>x : Symbol(x, Decl(jsdocTypeCast.js, 3, 12))
b;
>b : Symbol(b, Decl(jsdocTypeCast.js, 9, 7))
/** @type {'a' | 'b'} */
let c = /** @type {'a' | 'b'} */ (x); // Ok
>c : Symbol(c, Decl(jsdocTypeCast.js, 13, 7))
>x : Symbol(x, Decl(jsdocTypeCast.js, 3, 12))
c;
>c : Symbol(c, Decl(jsdocTypeCast.js, 13, 7))
}

View File

@ -0,0 +1,38 @@
=== tests/cases/compiler/jsdocTypeCast.js ===
/**
* @param {string} x
*/
function f(x) {
>f : (x: string) => void
>x : string
/** @type {'a' | 'b'} */
let a = (x); // Error
>a : "a" | "b"
>(x) : "a" | "b"
>x : string
a;
>a : "a" | "b"
/** @type {'a' | 'b'} */
let b = (((x))); // Error
>b : "a" | "b"
>(((x))) : "a" | "b"
>((x)) : string
>(x) : string
>x : string
b;
>b : "a" | "b"
/** @type {'a' | 'b'} */
let c = /** @type {'a' | 'b'} */ (x); // Ok
>c : "a" | "b"
>(x) : "a" | "b"
>x : string
c;
>c : "a" | "b"
}

View File

@ -0,0 +1,21 @@
// @allowJs: true
// @checkJs: true
// @outDir: ./out
// @filename: jsdocTypeCast.js
/**
* @param {string} x
*/
function f(x) {
/** @type {'a' | 'b'} */
let a = (x); // Error
a;
/** @type {'a' | 'b'} */
let b = (((x))); // Error
b;
/** @type {'a' | 'b'} */
let c = /** @type {'a' | 'b'} */ (x); // Ok
c;
}