From 475036950e768893474093215bbb0c5eaa19ea31 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 12 Feb 2021 03:07:14 +0200 Subject: [PATCH] fix(42133): fix instantiated undefined type from JS initializer (#42662) --- src/compiler/checker.ts | 4 ++-- .../typeFromJSInitializer.errors.txt | 7 ++++++ .../reference/typeFromJSInitializer.symbols | 19 +++++++++++++++ .../reference/typeFromJSInitializer.types | 24 +++++++++++++++++++ .../salsa/typeFromJSInitializer.ts | 7 ++++++ 5 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d33b94f4285..9d089eb7299 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19489,8 +19489,8 @@ namespace ts { } function isEmptyArrayLiteralType(type: Type): boolean { - const elementType = isArrayType(type) ? getTypeArguments(type)[0] : undefined; - return elementType === undefinedWideningType || elementType === implicitNeverType; + const elementType = getElementTypeOfArrayType(type); + return strictNullChecks ? elementType === implicitNeverType : elementType === undefinedWideningType; } function isTupleLikeType(type: Type): boolean { diff --git a/tests/baselines/reference/typeFromJSInitializer.errors.txt b/tests/baselines/reference/typeFromJSInitializer.errors.txt index 08d66a2a9f3..45ed31d6895 100644 --- a/tests/baselines/reference/typeFromJSInitializer.errors.txt +++ b/tests/baselines/reference/typeFromJSInitializer.errors.txt @@ -72,4 +72,11 @@ tests/cases/conformance/salsa/a.js(37,5): error TS2322: Type '"error"' is not as u = 'ok' l.push('ok') + + /** @type {(v: unknown) => v is undefined} */ + const isUndef = v => v === undefined; + const e = [1, undefined]; + + // should be undefined[] + const g = e.filter(isUndef); \ No newline at end of file diff --git a/tests/baselines/reference/typeFromJSInitializer.symbols b/tests/baselines/reference/typeFromJSInitializer.symbols index 2de03afed25..98c921e1cc1 100644 --- a/tests/baselines/reference/typeFromJSInitializer.symbols +++ b/tests/baselines/reference/typeFromJSInitializer.symbols @@ -175,3 +175,22 @@ l.push('ok') >l : Symbol(l, Decl(a.js, 45, 3)) >push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +/** @type {(v: unknown) => v is undefined} */ +const isUndef = v => v === undefined; +>isUndef : Symbol(isUndef, Decl(a.js, 55, 5)) +>v : Symbol(v, Decl(a.js, 55, 15)) +>v : Symbol(v, Decl(a.js, 55, 15)) +>undefined : Symbol(undefined) + +const e = [1, undefined]; +>e : Symbol(e, Decl(a.js, 56, 5)) +>undefined : Symbol(undefined) + +// should be undefined[] +const g = e.filter(isUndef); +>g : Symbol(g, Decl(a.js, 59, 5)) +>e.filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>e : Symbol(e, Decl(a.js, 56, 5)) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>isUndef : Symbol(isUndef, Decl(a.js, 55, 5)) + diff --git a/tests/baselines/reference/typeFromJSInitializer.types b/tests/baselines/reference/typeFromJSInitializer.types index 2ed82388598..1dd46220044 100644 --- a/tests/baselines/reference/typeFromJSInitializer.types +++ b/tests/baselines/reference/typeFromJSInitializer.types @@ -239,3 +239,27 @@ l.push('ok') >push : (...items: any[]) => number >'ok' : "ok" +/** @type {(v: unknown) => v is undefined} */ +const isUndef = v => v === undefined; +>isUndef : (v: unknown) => v is undefined +>v => v === undefined : (v: unknown) => v is undefined +>v : unknown +>v === undefined : boolean +>v : unknown +>undefined : undefined + +const e = [1, undefined]; +>e : (number | undefined)[] +>[1, undefined] : (number | undefined)[] +>1 : 1 +>undefined : undefined + +// should be undefined[] +const g = e.filter(isUndef); +>g : undefined[] +>e.filter(isUndef) : undefined[] +>e.filter : { (predicate: (value: number | undefined, index: number, array: (number | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: number | undefined, index: number, array: (number | undefined)[]) => unknown, thisArg?: any): (number | undefined)[]; } +>e : (number | undefined)[] +>filter : { (predicate: (value: number | undefined, index: number, array: (number | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: number | undefined, index: number, array: (number | undefined)[]) => unknown, thisArg?: any): (number | undefined)[]; } +>isUndef : (v: unknown) => v is undefined + diff --git a/tests/cases/conformance/salsa/typeFromJSInitializer.ts b/tests/cases/conformance/salsa/typeFromJSInitializer.ts index 39d2edb39b3..fc6a08822fb 100644 --- a/tests/cases/conformance/salsa/typeFromJSInitializer.ts +++ b/tests/cases/conformance/salsa/typeFromJSInitializer.ts @@ -57,3 +57,10 @@ u = {} u = 'ok' l.push('ok') + +/** @type {(v: unknown) => v is undefined} */ +const isUndef = v => v === undefined; +const e = [1, undefined]; + +// should be undefined[] +const g = e.filter(isUndef);