Do not narrow using JSDoc type assertion nodes (#56048)

This commit is contained in:
Mateusz Burzyński 2023-11-03 15:04:45 +01:00 committed by GitHub
parent 65f33a2e92
commit 6a9bc38da8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 113 additions and 0 deletions

View File

@ -173,6 +173,7 @@ import {
isJSDocEnumTag,
isJSDocTemplateTag,
isJSDocTypeAlias,
isJSDocTypeAssertion,
isJsonSourceFile,
isJsxNamespacedName,
isLeftHandSideExpression,
@ -1223,6 +1224,10 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
case SyntaxKind.CallExpression:
return hasNarrowableArgument(expr as CallExpression);
case SyntaxKind.ParenthesizedExpression:
if (isJSDocTypeAssertion(expr)) {
return false;
}
// fallthrough
case SyntaxKind.NonNullExpression:
return isNarrowingExpression((expr as ParenthesizedExpression | NonNullExpression).expression);
case SyntaxKind.BinaryExpression:

View File

@ -0,0 +1,22 @@
index.js(12,8): error TS2678: Type '"invalid"' is not comparable to type '"foo" | "bar"'.
==== index.js (1 errors) ====
let value = "";
switch (/** @type {"foo" | "bar"} */ (value)) {
case "bar":
value;
break;
case "foo":
value;
break;
case "invalid":
~~~~~~~~~
!!! error TS2678: Type '"invalid"' is not comparable to type '"foo" | "bar"'.
value;
break;
}

View File

@ -0,0 +1,28 @@
//// [tests/cases/compiler/parenthesizedJSDocCastDoesNotNarrow.ts] ////
=== index.js ===
let value = "";
>value : Symbol(value, Decl(index.js, 0, 3))
switch (/** @type {"foo" | "bar"} */ (value)) {
>value : Symbol(value, Decl(index.js, 0, 3))
case "bar":
value;
>value : Symbol(value, Decl(index.js, 0, 3))
break;
case "foo":
value;
>value : Symbol(value, Decl(index.js, 0, 3))
break;
case "invalid":
value;
>value : Symbol(value, Decl(index.js, 0, 3))
break;
}

View File

@ -0,0 +1,36 @@
//// [tests/cases/compiler/parenthesizedJSDocCastDoesNotNarrow.ts] ////
=== index.js ===
let value = "";
>value : string
>"" : ""
switch (/** @type {"foo" | "bar"} */ (value)) {
>(value) : "foo" | "bar"
>value : string
case "bar":
>"bar" : "bar"
value;
>value : string
break;
case "foo":
>"foo" : "foo"
value;
>value : string
break;
case "invalid":
>"invalid" : "invalid"
value;
>value : string
break;
}

View File

@ -0,0 +1,22 @@
// @strict: true
// @noEmit: true
// @checkJs: true
// @allowJs: true
// @filename: index.js
let value = "";
switch (/** @type {"foo" | "bar"} */ (value)) {
case "bar":
value;
break;
case "foo":
value;
break;
case "invalid":
value;
break;
}