mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Merge pull request #19912 from Microsoft/fixEmptyArrayInference
Fix empty array inference
This commit is contained in:
commit
a79610a403
@ -10898,22 +10898,25 @@ namespace ts {
|
||||
// it as an inference candidate. Hopefully, a better candidate will come along that does
|
||||
// not contain anyFunctionType when we come back to this argument for its second round
|
||||
// of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard
|
||||
// when constructing types from type parameters that had no inference candidates) and
|
||||
// implicitNeverType (which is used as the element type for empty array literals).
|
||||
if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType || source === implicitNeverType) {
|
||||
// when constructing types from type parameters that had no inference candidates).
|
||||
if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType) {
|
||||
return;
|
||||
}
|
||||
const inference = getInferenceInfoForType(target);
|
||||
if (inference) {
|
||||
if (!inference.isFixed) {
|
||||
if (!inference.candidates || priority < inference.priority) {
|
||||
// We give lowest priority to inferences of implicitNeverType (which is used as the
|
||||
// element type for empty array literals). Thus, inferences from empty array literals
|
||||
// only matter when no other inferences are made.
|
||||
const p = priority | (source === implicitNeverType ? InferencePriority.NeverType : 0);
|
||||
if (!inference.candidates || p < inference.priority) {
|
||||
inference.candidates = [source];
|
||||
inference.priority = priority;
|
||||
inference.priority = p;
|
||||
}
|
||||
else if (priority === inference.priority) {
|
||||
else if (p === inference.priority) {
|
||||
inference.candidates.push(source);
|
||||
}
|
||||
if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
|
||||
if (!(p & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
|
||||
inference.topLevel = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3613,6 +3613,7 @@ namespace ts {
|
||||
NakedTypeVariable = 1 << 1, // Naked type variable in union or intersection type
|
||||
MappedType = 1 << 2, // Reverse inference for mapped type
|
||||
ReturnType = 1 << 3, // Inference made from return type of generic function
|
||||
NeverType = 1 << 4, // Inference made from the never type
|
||||
}
|
||||
|
||||
export interface InferenceInfo {
|
||||
|
||||
@ -2142,6 +2142,7 @@ declare namespace ts {
|
||||
NakedTypeVariable = 2,
|
||||
MappedType = 4,
|
||||
ReturnType = 8,
|
||||
NeverType = 16,
|
||||
}
|
||||
interface InferenceInfo {
|
||||
typeParameter: TypeParameter;
|
||||
|
||||
@ -2142,6 +2142,7 @@ declare namespace ts {
|
||||
NakedTypeVariable = 2,
|
||||
MappedType = 4,
|
||||
ReturnType = 8,
|
||||
NeverType = 16,
|
||||
}
|
||||
interface InferenceInfo {
|
||||
typeParameter: TypeParameter;
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
//// [neverInference.ts]
|
||||
declare function f<T>(x: T[]): T;
|
||||
declare function f1<T>(x: T[]): T;
|
||||
|
||||
let neverArray: never[] = [];
|
||||
|
||||
let a1 = f([]); // {}
|
||||
let a2 = f(neverArray); // never
|
||||
let a1 = f1([]); // never
|
||||
let a2 = f1(neverArray); // never
|
||||
|
||||
// Repro from #19576
|
||||
|
||||
@ -21,11 +21,19 @@ declare function compareNumbers(x: number, y: number): number;
|
||||
declare function mkList<T>(items: T[], comparator: Comparator<T>): LinkedList<T>;
|
||||
|
||||
const list: LinkedList<number> = mkList([], compareNumbers);
|
||||
|
||||
// Repro from #19858
|
||||
|
||||
declare function f2<a>(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number): void;
|
||||
f2(Array.from([0]), [], (a1, a2) => a1 - a2);
|
||||
f2(Array.from([]), [0], (a1, a2) => a1 - a2);
|
||||
|
||||
|
||||
//// [neverInference.js]
|
||||
"use strict";
|
||||
var neverArray = [];
|
||||
var a1 = f([]); // {}
|
||||
var a2 = f(neverArray); // never
|
||||
var list = mkList([], compareNumbers);
|
||||
let neverArray = [];
|
||||
let a1 = f1([]); // never
|
||||
let a2 = f1(neverArray); // never
|
||||
const list = mkList([], compareNumbers);
|
||||
f2(Array.from([0]), [], (a1, a2) => a1 - a2);
|
||||
f2(Array.from([]), [0], (a1, a2) => a1 - a2);
|
||||
|
||||
@ -1,27 +1,27 @@
|
||||
=== tests/cases/conformance/types/never/neverInference.ts ===
|
||||
declare function f<T>(x: T[]): T;
|
||||
>f : Symbol(f, Decl(neverInference.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 0, 19))
|
||||
>x : Symbol(x, Decl(neverInference.ts, 0, 22))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 0, 19))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 0, 19))
|
||||
declare function f1<T>(x: T[]): T;
|
||||
>f1 : Symbol(f1, Decl(neverInference.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 0, 20))
|
||||
>x : Symbol(x, Decl(neverInference.ts, 0, 23))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 0, 20))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 0, 20))
|
||||
|
||||
let neverArray: never[] = [];
|
||||
>neverArray : Symbol(neverArray, Decl(neverInference.ts, 2, 3))
|
||||
|
||||
let a1 = f([]); // {}
|
||||
let a1 = f1([]); // never
|
||||
>a1 : Symbol(a1, Decl(neverInference.ts, 4, 3))
|
||||
>f : Symbol(f, Decl(neverInference.ts, 0, 0))
|
||||
>f1 : Symbol(f1, Decl(neverInference.ts, 0, 0))
|
||||
|
||||
let a2 = f(neverArray); // never
|
||||
let a2 = f1(neverArray); // never
|
||||
>a2 : Symbol(a2, Decl(neverInference.ts, 5, 3))
|
||||
>f : Symbol(f, Decl(neverInference.ts, 0, 0))
|
||||
>f1 : Symbol(f1, Decl(neverInference.ts, 0, 0))
|
||||
>neverArray : Symbol(neverArray, Decl(neverInference.ts, 2, 3))
|
||||
|
||||
// Repro from #19576
|
||||
|
||||
type Comparator<T> = (x: T, y: T) => number;
|
||||
>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23))
|
||||
>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 24))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 9, 16))
|
||||
>x : Symbol(x, Decl(neverInference.ts, 9, 22))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 9, 16))
|
||||
@ -34,7 +34,7 @@ interface LinkedList<T> {
|
||||
|
||||
comparator: Comparator<T>,
|
||||
>comparator : Symbol(LinkedList.comparator, Decl(neverInference.ts, 11, 25))
|
||||
>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23))
|
||||
>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 24))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 11, 21))
|
||||
|
||||
nodes: Node<T>
|
||||
@ -63,7 +63,7 @@ declare function mkList<T>(items: T[], comparator: Comparator<T>): LinkedList<T>
|
||||
>items : Symbol(items, Decl(neverInference.ts, 19, 27))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 19, 24))
|
||||
>comparator : Symbol(comparator, Decl(neverInference.ts, 19, 38))
|
||||
>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23))
|
||||
>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 24))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 19, 24))
|
||||
>LinkedList : Symbol(LinkedList, Decl(neverInference.ts, 9, 44))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 19, 24))
|
||||
@ -74,3 +74,38 @@ const list: LinkedList<number> = mkList([], compareNumbers);
|
||||
>mkList : Symbol(mkList, Decl(neverInference.ts, 18, 62))
|
||||
>compareNumbers : Symbol(compareNumbers, Decl(neverInference.ts, 16, 49))
|
||||
|
||||
// Repro from #19858
|
||||
|
||||
declare function f2<a>(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number): void;
|
||||
>f2 : Symbol(f2, Decl(neverInference.ts, 21, 60))
|
||||
>a : Symbol(a, Decl(neverInference.ts, 25, 20))
|
||||
>as1 : Symbol(as1, Decl(neverInference.ts, 25, 23))
|
||||
>a : Symbol(a, Decl(neverInference.ts, 25, 20))
|
||||
>as2 : Symbol(as2, Decl(neverInference.ts, 25, 32))
|
||||
>a : Symbol(a, Decl(neverInference.ts, 25, 20))
|
||||
>cmp : Symbol(cmp, Decl(neverInference.ts, 25, 42))
|
||||
>a1 : Symbol(a1, Decl(neverInference.ts, 25, 49))
|
||||
>a : Symbol(a, Decl(neverInference.ts, 25, 20))
|
||||
>a2 : Symbol(a2, Decl(neverInference.ts, 25, 55))
|
||||
>a : Symbol(a, Decl(neverInference.ts, 25, 20))
|
||||
|
||||
f2(Array.from([0]), [], (a1, a2) => a1 - a2);
|
||||
>f2 : Symbol(f2, Decl(neverInference.ts, 21, 60))
|
||||
>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>a1 : Symbol(a1, Decl(neverInference.ts, 26, 25))
|
||||
>a2 : Symbol(a2, Decl(neverInference.ts, 26, 28))
|
||||
>a1 : Symbol(a1, Decl(neverInference.ts, 26, 25))
|
||||
>a2 : Symbol(a2, Decl(neverInference.ts, 26, 28))
|
||||
|
||||
f2(Array.from([]), [0], (a1, a2) => a1 - a2);
|
||||
>f2 : Symbol(f2, Decl(neverInference.ts, 21, 60))
|
||||
>Array.from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>from : Symbol(ArrayConstructor.from, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
|
||||
>a1 : Symbol(a1, Decl(neverInference.ts, 27, 25))
|
||||
>a2 : Symbol(a2, Decl(neverInference.ts, 27, 28))
|
||||
>a1 : Symbol(a1, Decl(neverInference.ts, 27, 25))
|
||||
>a2 : Symbol(a2, Decl(neverInference.ts, 27, 28))
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
=== tests/cases/conformance/types/never/neverInference.ts ===
|
||||
declare function f<T>(x: T[]): T;
|
||||
>f : <T>(x: T[]) => T
|
||||
declare function f1<T>(x: T[]): T;
|
||||
>f1 : <T>(x: T[]) => T
|
||||
>T : T
|
||||
>x : T[]
|
||||
>T : T
|
||||
@ -10,16 +10,16 @@ let neverArray: never[] = [];
|
||||
>neverArray : never[]
|
||||
>[] : never[]
|
||||
|
||||
let a1 = f([]); // {}
|
||||
>a1 : {}
|
||||
>f([]) : {}
|
||||
>f : <T>(x: T[]) => T
|
||||
let a1 = f1([]); // never
|
||||
>a1 : never
|
||||
>f1([]) : never
|
||||
>f1 : <T>(x: T[]) => T
|
||||
>[] : never[]
|
||||
|
||||
let a2 = f(neverArray); // never
|
||||
let a2 = f1(neverArray); // never
|
||||
>a2 : never
|
||||
>f(neverArray) : never
|
||||
>f : <T>(x: T[]) => T
|
||||
>f1(neverArray) : never
|
||||
>f1 : <T>(x: T[]) => T
|
||||
>neverArray : never[]
|
||||
|
||||
// Repro from #19576
|
||||
@ -81,3 +81,52 @@ const list: LinkedList<number> = mkList([], compareNumbers);
|
||||
>[] : never[]
|
||||
>compareNumbers : (x: number, y: number) => number
|
||||
|
||||
// Repro from #19858
|
||||
|
||||
declare function f2<a>(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number): void;
|
||||
>f2 : <a>(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number) => void
|
||||
>a : a
|
||||
>as1 : a[]
|
||||
>a : a
|
||||
>as2 : a[]
|
||||
>a : a
|
||||
>cmp : (a1: a, a2: a) => number
|
||||
>a1 : a
|
||||
>a : a
|
||||
>a2 : a
|
||||
>a : a
|
||||
|
||||
f2(Array.from([0]), [], (a1, a2) => a1 - a2);
|
||||
>f2(Array.from([0]), [], (a1, a2) => a1 - a2) : void
|
||||
>f2 : <a>(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number) => void
|
||||
>Array.from([0]) : number[]
|
||||
>Array.from : { <T>(iterable: Iterable<T>): T[]; <T, U>(iterable: Iterable<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
||||
>Array : ArrayConstructor
|
||||
>from : { <T>(iterable: Iterable<T>): T[]; <T, U>(iterable: Iterable<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
||||
>[0] : number[]
|
||||
>0 : 0
|
||||
>[] : never[]
|
||||
>(a1, a2) => a1 - a2 : (a1: number, a2: number) => number
|
||||
>a1 : number
|
||||
>a2 : number
|
||||
>a1 - a2 : number
|
||||
>a1 : number
|
||||
>a2 : number
|
||||
|
||||
f2(Array.from([]), [0], (a1, a2) => a1 - a2);
|
||||
>f2(Array.from([]), [0], (a1, a2) => a1 - a2) : void
|
||||
>f2 : <a>(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number) => void
|
||||
>Array.from([]) : never[]
|
||||
>Array.from : { <T>(iterable: Iterable<T>): T[]; <T, U>(iterable: Iterable<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
||||
>Array : ArrayConstructor
|
||||
>from : { <T>(iterable: Iterable<T>): T[]; <T, U>(iterable: Iterable<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; <T>(arrayLike: ArrayLike<T>): T[]; <T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[]; }
|
||||
>[] : never[]
|
||||
>[0] : number[]
|
||||
>0 : 0
|
||||
>(a1, a2) => a1 - a2 : (a1: number, a2: number) => number
|
||||
>a1 : number
|
||||
>a2 : number
|
||||
>a1 - a2 : number
|
||||
>a1 : number
|
||||
>a2 : number
|
||||
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
// @strict: true
|
||||
// @target: es2015
|
||||
|
||||
declare function f<T>(x: T[]): T;
|
||||
declare function f1<T>(x: T[]): T;
|
||||
|
||||
let neverArray: never[] = [];
|
||||
|
||||
let a1 = f([]); // {}
|
||||
let a2 = f(neverArray); // never
|
||||
let a1 = f1([]); // never
|
||||
let a2 = f1(neverArray); // never
|
||||
|
||||
// Repro from #19576
|
||||
|
||||
@ -22,3 +23,9 @@ declare function compareNumbers(x: number, y: number): number;
|
||||
declare function mkList<T>(items: T[], comparator: Comparator<T>): LinkedList<T>;
|
||||
|
||||
const list: LinkedList<number> = mkList([], compareNumbers);
|
||||
|
||||
// Repro from #19858
|
||||
|
||||
declare function f2<a>(as1: a[], as2: a[], cmp: (a1: a, a2: a) => number): void;
|
||||
f2(Array.from([0]), [], (a1, a2) => a1 - a2);
|
||||
f2(Array.from([]), [0], (a1, a2) => a1 - a2);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user