Narrow types by typeof operands with extra parenthesis (#60928)

This commit is contained in:
Mateusz Burzyński
2025-01-07 21:26:00 +01:00
committed by GitHub
parent c0b3ff2da1
commit a5196c7d3b
4 changed files with 106 additions and 3 deletions

View File

@@ -1318,9 +1318,11 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
case SyntaxKind.ExclamationEqualsToken:
case SyntaxKind.EqualsEqualsEqualsToken:
case SyntaxKind.ExclamationEqualsEqualsToken:
return isNarrowableOperand(expr.left) || isNarrowableOperand(expr.right) ||
isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right) ||
(isBooleanLiteral(expr.right) && isNarrowingExpression(expr.left) || isBooleanLiteral(expr.left) && isNarrowingExpression(expr.right));
const left = skipParentheses(expr.left);
const right = skipParentheses(expr.right);
return isNarrowableOperand(left) || isNarrowableOperand(right) ||
isNarrowingTypeofOperands(right, left) || isNarrowingTypeofOperands(left, right) ||
(isBooleanLiteral(right) && isNarrowingExpression(left) || isBooleanLiteral(left) && isNarrowingExpression(right));
case SyntaxKind.InstanceOfKeyword:
return isNarrowableOperand(expr.left);
case SyntaxKind.InKeyword:

View File

@@ -0,0 +1,30 @@
//// [tests/cases/compiler/narrowingTypeofParenthesized1.ts] ////
=== narrowingTypeofParenthesized1.ts ===
// https://github.com/microsoft/TypeScript/issues/42203
declare const foo: string;
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
if ((typeof foo) === "string") {
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
foo;
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
} else {
foo;
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
}
if (typeof foo === ("string")) {
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
foo;
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
} else {
foo;
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
}

View File

@@ -0,0 +1,53 @@
//// [tests/cases/compiler/narrowingTypeofParenthesized1.ts] ////
=== narrowingTypeofParenthesized1.ts ===
// https://github.com/microsoft/TypeScript/issues/42203
declare const foo: string;
>foo : string
> : ^^^^^^
if ((typeof foo) === "string") {
>(typeof foo) === "string" : boolean
> : ^^^^^^^
>(typeof foo) : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>typeof foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>foo : string
> : ^^^^^^
>"string" : "string"
> : ^^^^^^^^
foo;
>foo : string
> : ^^^^^^
} else {
foo;
>foo : never
> : ^^^^^
}
if (typeof foo === ("string")) {
>typeof foo === ("string") : boolean
> : ^^^^^^^
>typeof foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>foo : string
> : ^^^^^^
>("string") : "string"
> : ^^^^^^^^
>"string" : "string"
> : ^^^^^^^^
foo;
>foo : string
> : ^^^^^^
} else {
foo;
>foo : never
> : ^^^^^
}

View File

@@ -0,0 +1,18 @@
// @strict: true
// @noEmit: true
// https://github.com/microsoft/TypeScript/issues/42203
declare const foo: string;
if ((typeof foo) === "string") {
foo;
} else {
foo;
}
if (typeof foo === ("string")) {
foo;
} else {
foo;
}