From bf077f24c0baad3578f39918c0c76539030cc260 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 26 Aug 2024 12:10:10 -0700 Subject: [PATCH 1/2] Add failing test --- .../reference/predicateSemantics.errors.txt | 11 +++++++++-- tests/baselines/reference/predicateSemantics.js | 10 +++++++++- .../reference/predicateSemantics.symbols | 9 +++++++++ .../baselines/reference/predicateSemantics.types | 15 +++++++++++++++ tests/cases/compiler/predicateSemantics.ts | 5 +++++ 5 files changed, 47 insertions(+), 3 deletions(-) diff --git a/tests/baselines/reference/predicateSemantics.errors.txt b/tests/baselines/reference/predicateSemantics.errors.txt index 883ce4570983b..ca5e40d67ebb3 100644 --- a/tests/baselines/reference/predicateSemantics.errors.txt +++ b/tests/baselines/reference/predicateSemantics.errors.txt @@ -9,9 +9,10 @@ predicateSemantics.ts(33,8): error TS2872: This kind of expression is always tru predicateSemantics.ts(34,11): error TS2872: This kind of expression is always truthy. predicateSemantics.ts(35,8): error TS2872: This kind of expression is always truthy. predicateSemantics.ts(36,8): error TS2872: This kind of expression is always truthy. +predicateSemantics.ts(43,12): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish. -==== predicateSemantics.ts (11 errors) ==== +==== predicateSemantics.ts (12 errors) ==== declare let cond: any; // OK: One or other operand is possibly nullish @@ -73,4 +74,10 @@ predicateSemantics.ts(36,8): error TS2872: This kind of expression is always tru // Should be OK console.log((cond || undefined) && 1 / cond); - \ No newline at end of file + + function foo(this: Object | undefined) { + // Should be OK + return this ?? 0; + ~~~~ +!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish. + } \ No newline at end of file diff --git a/tests/baselines/reference/predicateSemantics.js b/tests/baselines/reference/predicateSemantics.js index 4ed294189332c..eb0b66516b62c 100644 --- a/tests/baselines/reference/predicateSemantics.js +++ b/tests/baselines/reference/predicateSemantics.js @@ -40,7 +40,11 @@ while ((({}))) { } // Should be OK console.log((cond || undefined) && 1 / cond); - + +function foo(this: Object | undefined) { + // Should be OK + return this ?? 0; +} //// [predicateSemantics.js] var _a, _b, _c, _d, _e, _f; @@ -80,3 +84,7 @@ while (({})) { } while ((({}))) { } // Should be OK console.log((cond || undefined) && 1 / cond); +function foo() { + // Should be OK + return this !== null && this !== void 0 ? this : 0; +} diff --git a/tests/baselines/reference/predicateSemantics.symbols b/tests/baselines/reference/predicateSemantics.symbols index 39ce291427a74..790e965f988cc 100644 --- a/tests/baselines/reference/predicateSemantics.symbols +++ b/tests/baselines/reference/predicateSemantics.symbols @@ -70,3 +70,12 @@ console.log((cond || undefined) && 1 / cond); >undefined : Symbol(undefined) >cond : Symbol(cond, Decl(predicateSemantics.ts, 0, 11)) +function foo(this: Object | undefined) { +>foo : Symbol(foo, Decl(predicateSemantics.ts, 38, 45)) +>this : Symbol(this, Decl(predicateSemantics.ts, 40, 13)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + // Should be OK + return this ?? 0; +>this : Symbol(this, Decl(predicateSemantics.ts, 40, 13)) +} diff --git a/tests/baselines/reference/predicateSemantics.types b/tests/baselines/reference/predicateSemantics.types index b4f418ce33943..3d3eba6683e25 100644 --- a/tests/baselines/reference/predicateSemantics.types +++ b/tests/baselines/reference/predicateSemantics.types @@ -219,3 +219,18 @@ console.log((cond || undefined) && 1 / cond); >cond : any > : ^^^ +function foo(this: Object | undefined) { +>foo : (this: Object | undefined) => Object | 0 +> : ^ ^^ ^^^^^^^^^^^^^^^ +>this : Object +> : ^^^^^^ + + // Should be OK + return this ?? 0; +>this ?? 0 : 0 | Object +> : ^^^^^^^^^^ +>this : Object +> : ^^^^^^ +>0 : 0 +> : ^ +} diff --git a/tests/cases/compiler/predicateSemantics.ts b/tests/cases/compiler/predicateSemantics.ts index 4069c1da6eec7..d6e12b297b25b 100644 --- a/tests/cases/compiler/predicateSemantics.ts +++ b/tests/cases/compiler/predicateSemantics.ts @@ -37,3 +37,8 @@ while ((({}))) { } // Should be OK console.log((cond || undefined) && 1 / cond); + +function foo(this: Object | undefined) { + // Should be OK + return this ?? 0; +} \ No newline at end of file From ea2c597187123c28b7d914fa37b0bc43a3273122 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 26 Aug 2024 12:12:07 -0700 Subject: [PATCH 2/2] `this` is possibly nullish. Fixes #59755 --- src/compiler/checker.ts | 1 + tests/baselines/reference/predicateSemantics.errors.txt | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 13523516bab99..a6561122df5fe 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -39818,6 +39818,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.NewExpression: case SyntaxKind.PropertyAccessExpression: case SyntaxKind.YieldExpression: + case SyntaxKind.ThisKeyword: return PredicateSemantics.Sometimes; case SyntaxKind.BinaryExpression: // List of operators that can produce null/undefined: diff --git a/tests/baselines/reference/predicateSemantics.errors.txt b/tests/baselines/reference/predicateSemantics.errors.txt index ca5e40d67ebb3..14251121358c4 100644 --- a/tests/baselines/reference/predicateSemantics.errors.txt +++ b/tests/baselines/reference/predicateSemantics.errors.txt @@ -9,10 +9,9 @@ predicateSemantics.ts(33,8): error TS2872: This kind of expression is always tru predicateSemantics.ts(34,11): error TS2872: This kind of expression is always truthy. predicateSemantics.ts(35,8): error TS2872: This kind of expression is always truthy. predicateSemantics.ts(36,8): error TS2872: This kind of expression is always truthy. -predicateSemantics.ts(43,12): error TS2869: Right operand of ?? is unreachable because the left operand is never nullish. -==== predicateSemantics.ts (12 errors) ==== +==== predicateSemantics.ts (11 errors) ==== declare let cond: any; // OK: One or other operand is possibly nullish @@ -78,6 +77,4 @@ predicateSemantics.ts(43,12): error TS2869: Right operand of ?? is unreachable b function foo(this: Object | undefined) { // Should be OK return this ?? 0; - ~~~~ -!!! error TS2869: Right operand of ?? is unreachable because the left operand is never nullish. } \ No newline at end of file