Skip to content

Commit

Permalink
Narrow types by typeof operands with extra parenthesis
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Jan 7, 2025
1 parent c0b3ff2 commit 199f492
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 3 deletions.
8 changes: 5 additions & 3 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
30 changes: 30 additions & 0 deletions tests/baselines/reference/narrowingTypeofParenthesized1.symbols
Original file line number Diff line number Diff line change
@@ -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))
}

53 changes: 53 additions & 0 deletions tests/baselines/reference/narrowingTypeofParenthesized1.types
Original file line number Diff line number Diff line change
@@ -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
> : ^^^^^
}

18 changes: 18 additions & 0 deletions tests/cases/compiler/narrowingTypeofParenthesized1.ts
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit 199f492

Please sign in to comment.