From 58781b0d4135ba4bfdc707d125a12579e31f0239 Mon Sep 17 00:00:00 2001 From: uhyo Date: Tue, 13 Oct 2020 00:21:47 +0900 Subject: [PATCH] allow type narrowing with NonNullExpression --- src/compiler/binder.ts | 3 ++- src/compiler/checker.ts | 3 ++- .../narrowingWithNonNullExpression.js | 10 +++++++ .../narrowingWithNonNullExpression.symbols | 14 ++++++++++ .../narrowingWithNonNullExpression.types | 27 +++++++++++++++++++ .../narrowingWithNonNullExpression.ts | 3 +++ 6 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/narrowingWithNonNullExpression.js create mode 100644 tests/baselines/reference/narrowingWithNonNullExpression.symbols create mode 100644 tests/baselines/reference/narrowingWithNonNullExpression.types create mode 100644 tests/cases/compiler/narrowingWithNonNullExpression.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 5e7695ffef366..1b3a32a0c2c24 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -844,7 +844,8 @@ namespace ts { case SyntaxKind.CallExpression: return hasNarrowableArgument(expr); case SyntaxKind.ParenthesizedExpression: - return isNarrowingExpression((expr).expression); + case SyntaxKind.NonNullExpression: + return isNarrowingExpression((expr).expression); case SyntaxKind.BinaryExpression: return isNarrowingBinaryExpression(expr); case SyntaxKind.PrefixUnaryExpression: diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6f3b94e0b409c..5bd4cb9f63c7a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22554,7 +22554,8 @@ namespace ts { case SyntaxKind.CallExpression: return narrowTypeByCallExpression(type, expr, assumeTrue); case SyntaxKind.ParenthesizedExpression: - return narrowType(type, (expr).expression, assumeTrue); + case SyntaxKind.NonNullExpression: + return narrowType(type, (expr).expression, assumeTrue); case SyntaxKind.BinaryExpression: return narrowTypeByBinaryExpression(type, expr, assumeTrue); case SyntaxKind.PrefixUnaryExpression: diff --git a/tests/baselines/reference/narrowingWithNonNullExpression.js b/tests/baselines/reference/narrowingWithNonNullExpression.js new file mode 100644 index 0000000000000..eaf0006c8db02 --- /dev/null +++ b/tests/baselines/reference/narrowingWithNonNullExpression.js @@ -0,0 +1,10 @@ +//// [narrowingWithNonNullExpression.ts] +const m = ''.match(''); +m! && m[0]; +m?.[0]! && m[0]; + + +//// [narrowingWithNonNullExpression.js] +var m = ''.match(''); +m && m[0]; +(m === null || m === void 0 ? void 0 : m[0]) && m[0]; diff --git a/tests/baselines/reference/narrowingWithNonNullExpression.symbols b/tests/baselines/reference/narrowingWithNonNullExpression.symbols new file mode 100644 index 0000000000000..ab95237830217 --- /dev/null +++ b/tests/baselines/reference/narrowingWithNonNullExpression.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/narrowingWithNonNullExpression.ts === +const m = ''.match(''); +>m : Symbol(m, Decl(narrowingWithNonNullExpression.ts, 0, 5)) +>''.match : Symbol(String.match, Decl(lib.es5.d.ts, --, --)) +>match : Symbol(String.match, Decl(lib.es5.d.ts, --, --)) + +m! && m[0]; +>m : Symbol(m, Decl(narrowingWithNonNullExpression.ts, 0, 5)) +>m : Symbol(m, Decl(narrowingWithNonNullExpression.ts, 0, 5)) + +m?.[0]! && m[0]; +>m : Symbol(m, Decl(narrowingWithNonNullExpression.ts, 0, 5)) +>m : Symbol(m, Decl(narrowingWithNonNullExpression.ts, 0, 5)) + diff --git a/tests/baselines/reference/narrowingWithNonNullExpression.types b/tests/baselines/reference/narrowingWithNonNullExpression.types new file mode 100644 index 0000000000000..be9df1922c163 --- /dev/null +++ b/tests/baselines/reference/narrowingWithNonNullExpression.types @@ -0,0 +1,27 @@ +=== tests/cases/compiler/narrowingWithNonNullExpression.ts === +const m = ''.match(''); +>m : RegExpMatchArray +>''.match('') : RegExpMatchArray +>''.match : (regexp: string | RegExp) => RegExpMatchArray +>'' : "" +>match : (regexp: string | RegExp) => RegExpMatchArray +>'' : "" + +m! && m[0]; +>m! && m[0] : string +>m! : RegExpMatchArray +>m : RegExpMatchArray +>m[0] : string +>m : RegExpMatchArray +>0 : 0 + +m?.[0]! && m[0]; +>m?.[0]! && m[0] : string +>m?.[0]! : string +>m?.[0] : string +>m : RegExpMatchArray +>0 : 0 +>m[0] : string +>m : RegExpMatchArray +>0 : 0 + diff --git a/tests/cases/compiler/narrowingWithNonNullExpression.ts b/tests/cases/compiler/narrowingWithNonNullExpression.ts new file mode 100644 index 0000000000000..8e1f5cbed0381 --- /dev/null +++ b/tests/cases/compiler/narrowingWithNonNullExpression.ts @@ -0,0 +1,3 @@ +const m = ''.match(''); +m! && m[0]; +m?.[0]! && m[0];