diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e7572eca66b..c89c3324f02 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -845,7 +845,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 839f439368c..8c97bdd424d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22618,7 +22618,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 00000000000..eaf0006c8db --- /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 00000000000..ab952378302 --- /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 00000000000..be9df1922c1 --- /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 00000000000..8e1f5cbed03 --- /dev/null +++ b/tests/cases/compiler/narrowingWithNonNullExpression.ts @@ -0,0 +1,3 @@ +const m = ''.match(''); +m! && m[0]; +m?.[0]! && m[0];