Skip to content

Commit a4a7992

Browse files
committed
Compute more precise syntactic truthy semantics for comma expressions
1 parent 56a0825 commit a4a7992

File tree

6 files changed

+76
-1
lines changed

6 files changed

+76
-1
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44715,6 +44715,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4471544715
return !!(node as StringLiteral | NoSubstitutionTemplateLiteral).text ? PredicateSemantics.Always : PredicateSemantics.Never;
4471644716
case SyntaxKind.ConditionalExpression:
4471744717
return getSyntacticTruthySemantics((node as ConditionalExpression).whenTrue) | getSyntacticTruthySemantics((node as ConditionalExpression).whenFalse);
44718+
case SyntaxKind.BinaryExpression:
44719+
if ((node as BinaryExpression).operatorToken.kind !== SyntaxKind.CommaToken) {
44720+
break;
44721+
}
44722+
return getSyntacticTruthySemantics((node as BinaryExpression).right);
4471844723
case SyntaxKind.Identifier:
4471944724
if (getResolvedSymbol(node as Identifier) === undefinedSymbol) {
4472044725
return PredicateSemantics.Never;

tests/baselines/reference/predicateSemantics.errors.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ predicateSemantics.ts(52,14): error TS2695: Left side of comma operator is unuse
1414
predicateSemantics.ts(52,14): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
1515
predicateSemantics.ts(70,1): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
1616
predicateSemantics.ts(71,1): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
17+
predicateSemantics.ts(75,5): error TS2872: This kind of expression is always truthy.
1718

1819

19-
==== predicateSemantics.ts (16 errors) ====
20+
==== predicateSemantics.ts (17 errors) ====
2021
declare let cond: any;
2122

2223
// OK: One or other operand is possibly nullish
@@ -120,4 +121,11 @@ predicateSemantics.ts(71,1): error TS2869: Right operand of ?? is unreachable be
120121
`foo` ?? 32; // error
121122
~~~~~
122123
!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish.
124+
125+
// https://github.com/microsoft/TypeScript/issues/60822
126+
declare function test60822(arg: string, arg2?: string): string | null;
127+
if (test60822("foo"), "bar") {} // error
128+
~~~~~~~~~~~~~~~~~~~~~~~
129+
!!! error TS2872: This kind of expression is always truthy.
130+
if (test60822("foo"), test60822("bar")) {} // ok
123131

tests/baselines/reference/predicateSemantics.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ tag`foo${1}` ?? 32; // ok
7272

7373
`foo${1}` ?? 32; // error
7474
`foo` ?? 32; // error
75+
76+
// https://github.com/microsoft/TypeScript/issues/60822
77+
declare function test60822(arg: string, arg2?: string): string | null;
78+
if (test60822("foo"), "bar") {} // error
79+
if (test60822("foo"), test60822("bar")) {} // ok
7580

7681

7782
//// [predicateSemantics.js]
@@ -140,3 +145,5 @@ var X = /** @class */ (function () {
140145
(_k = tag(__makeTemplateObject(["foo", ""], ["foo", ""]), 1)) !== null && _k !== void 0 ? _k : 32; // ok
141146
(_l = "foo".concat(1)) !== null && _l !== void 0 ? _l : 32; // error
142147
"foo" !== null && "foo" !== void 0 ? "foo" : 32; // error
148+
if (test60822("foo"), "bar") { } // error
149+
if (test60822("foo"), test60822("bar")) { } // ok

tests/baselines/reference/predicateSemantics.symbols

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,16 @@ tag`foo${1}` ?? 32; // ok
137137
`foo${1}` ?? 32; // error
138138
`foo` ?? 32; // error
139139

140+
// https://github.com/microsoft/TypeScript/issues/60822
141+
declare function test60822(arg: string, arg2?: string): string | null;
142+
>test60822 : Symbol(test60822, Decl(predicateSemantics.ts, 70, 12))
143+
>arg : Symbol(arg, Decl(predicateSemantics.ts, 73, 27))
144+
>arg2 : Symbol(arg2, Decl(predicateSemantics.ts, 73, 39))
145+
146+
if (test60822("foo"), "bar") {} // error
147+
>test60822 : Symbol(test60822, Decl(predicateSemantics.ts, 70, 12))
148+
149+
if (test60822("foo"), test60822("bar")) {} // ok
150+
>test60822 : Symbol(test60822, Decl(predicateSemantics.ts, 70, 12))
151+
>test60822 : Symbol(test60822, Decl(predicateSemantics.ts, 70, 12))
152+

tests/baselines/reference/predicateSemantics.types

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,40 @@ tag`foo${1}` ?? 32; // ok
375375
>32 : 32
376376
> : ^^
377377

378+
// https://github.com/microsoft/TypeScript/issues/60822
379+
declare function test60822(arg: string, arg2?: string): string | null;
380+
>test60822 : (arg: string, arg2?: string) => string | null
381+
> : ^ ^^ ^^ ^^^ ^^^^^
382+
>arg : string
383+
> : ^^^^^^
384+
>arg2 : string
385+
> : ^^^^^^
386+
387+
if (test60822("foo"), "bar") {} // error
388+
>test60822("foo"), "bar" : "bar"
389+
> : ^^^^^
390+
>test60822("foo") : string
391+
> : ^^^^^^
392+
>test60822 : (arg: string, arg2?: string) => string | null
393+
> : ^ ^^ ^^ ^^^ ^^^^^
394+
>"foo" : "foo"
395+
> : ^^^^^
396+
>"bar" : "bar"
397+
> : ^^^^^
398+
399+
if (test60822("foo"), test60822("bar")) {} // ok
400+
>test60822("foo"), test60822("bar") : string
401+
> : ^^^^^^
402+
>test60822("foo") : string
403+
> : ^^^^^^
404+
>test60822 : (arg: string, arg2?: string) => string | null
405+
> : ^ ^^ ^^ ^^^ ^^^^^
406+
>"foo" : "foo"
407+
> : ^^^^^
408+
>test60822("bar") : string
409+
> : ^^^^^^
410+
>test60822 : (arg: string, arg2?: string) => string | null
411+
> : ^ ^^ ^^ ^^^ ^^^^^
412+
>"bar" : "bar"
413+
> : ^^^^^
414+

tests/cases/compiler/predicateSemantics.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,8 @@ tag`foo${1}` ?? 32; // ok
6969

7070
`foo${1}` ?? 32; // error
7171
`foo` ?? 32; // error
72+
73+
// https://github.com/microsoft/TypeScript/issues/60822
74+
declare function test60822(arg: string, arg2?: string): string | null;
75+
if (test60822("foo"), "bar") {} // error
76+
if (test60822("foo"), test60822("bar")) {} // ok

0 commit comments

Comments
 (0)