Skip to content

Commit a5196c7

Browse files
authored
Narrow types by typeof operands with extra parenthesis (microsoft#60928)
1 parent c0b3ff2 commit a5196c7

File tree

4 files changed

+106
-3
lines changed

4 files changed

+106
-3
lines changed

src/compiler/binder.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1318,9 +1318,11 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
13181318
case SyntaxKind.ExclamationEqualsToken:
13191319
case SyntaxKind.EqualsEqualsEqualsToken:
13201320
case SyntaxKind.ExclamationEqualsEqualsToken:
1321-
return isNarrowableOperand(expr.left) || isNarrowableOperand(expr.right) ||
1322-
isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right) ||
1323-
(isBooleanLiteral(expr.right) && isNarrowingExpression(expr.left) || isBooleanLiteral(expr.left) && isNarrowingExpression(expr.right));
1321+
const left = skipParentheses(expr.left);
1322+
const right = skipParentheses(expr.right);
1323+
return isNarrowableOperand(left) || isNarrowableOperand(right) ||
1324+
isNarrowingTypeofOperands(right, left) || isNarrowingTypeofOperands(left, right) ||
1325+
(isBooleanLiteral(right) && isNarrowingExpression(left) || isBooleanLiteral(left) && isNarrowingExpression(right));
13241326
case SyntaxKind.InstanceOfKeyword:
13251327
return isNarrowableOperand(expr.left);
13261328
case SyntaxKind.InKeyword:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//// [tests/cases/compiler/narrowingTypeofParenthesized1.ts] ////
2+
3+
=== narrowingTypeofParenthesized1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/42203
5+
6+
declare const foo: string;
7+
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
8+
9+
if ((typeof foo) === "string") {
10+
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
11+
12+
foo;
13+
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
14+
15+
} else {
16+
foo;
17+
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
18+
}
19+
20+
if (typeof foo === ("string")) {
21+
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
22+
23+
foo;
24+
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
25+
26+
} else {
27+
foo;
28+
>foo : Symbol(foo, Decl(narrowingTypeofParenthesized1.ts, 2, 13))
29+
}
30+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//// [tests/cases/compiler/narrowingTypeofParenthesized1.ts] ////
2+
3+
=== narrowingTypeofParenthesized1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/42203
5+
6+
declare const foo: string;
7+
>foo : string
8+
> : ^^^^^^
9+
10+
if ((typeof foo) === "string") {
11+
>(typeof foo) === "string" : boolean
12+
> : ^^^^^^^
13+
>(typeof foo) : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
14+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
>typeof foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
16+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
>foo : string
18+
> : ^^^^^^
19+
>"string" : "string"
20+
> : ^^^^^^^^
21+
22+
foo;
23+
>foo : string
24+
> : ^^^^^^
25+
26+
} else {
27+
foo;
28+
>foo : never
29+
> : ^^^^^
30+
}
31+
32+
if (typeof foo === ("string")) {
33+
>typeof foo === ("string") : boolean
34+
> : ^^^^^^^
35+
>typeof foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
36+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
37+
>foo : string
38+
> : ^^^^^^
39+
>("string") : "string"
40+
> : ^^^^^^^^
41+
>"string" : "string"
42+
> : ^^^^^^^^
43+
44+
foo;
45+
>foo : string
46+
> : ^^^^^^
47+
48+
} else {
49+
foo;
50+
>foo : never
51+
> : ^^^^^
52+
}
53+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// https://github.com/microsoft/TypeScript/issues/42203
5+
6+
declare const foo: string;
7+
8+
if ((typeof foo) === "string") {
9+
foo;
10+
} else {
11+
foo;
12+
}
13+
14+
if (typeof foo === ("string")) {
15+
foo;
16+
} else {
17+
foo;
18+
}

0 commit comments

Comments
 (0)