mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #19745 from Microsoft/emptyArrayInference
No inference from empty array literals
This commit is contained in:
@@ -283,6 +283,7 @@ namespace ts {
|
||||
const voidType = createIntrinsicType(TypeFlags.Void, "void");
|
||||
const neverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
const silentNeverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never");
|
||||
const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object");
|
||||
|
||||
const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||
@@ -7691,7 +7692,7 @@ namespace ts {
|
||||
|
||||
function getIndexTypeOrString(type: Type): Type {
|
||||
const indexType = getIndexType(type);
|
||||
return indexType !== neverType ? indexType : stringType;
|
||||
return indexType.flags & TypeFlags.Never ? stringType : indexType;
|
||||
}
|
||||
|
||||
function getTypeFromTypeOperatorNode(node: TypeOperatorNode) {
|
||||
@@ -8880,8 +8881,8 @@ namespace ts {
|
||||
function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map<RelationComparisonResult>, errorReporter?: ErrorReporter) {
|
||||
const s = source.flags;
|
||||
const t = target.flags;
|
||||
if (t & TypeFlags.Never) return false;
|
||||
if (t & TypeFlags.Any || s & TypeFlags.Never) return true;
|
||||
if (t & TypeFlags.Never) return false;
|
||||
if (s & TypeFlags.StringLike && t & TypeFlags.String) return true;
|
||||
if (s & TypeFlags.StringLiteral && s & TypeFlags.EnumLiteral &&
|
||||
t & TypeFlags.StringLiteral && !(t & TypeFlags.EnumLiteral) &&
|
||||
@@ -10348,7 +10349,7 @@ namespace ts {
|
||||
|
||||
function isEmptyArrayLiteralType(type: Type): boolean {
|
||||
const elementType = isArrayType(type) ? (<TypeReference>type).typeArguments[0] : undefined;
|
||||
return elementType === undefinedWideningType || elementType === neverType;
|
||||
return elementType === undefinedWideningType || elementType === implicitNeverType;
|
||||
}
|
||||
|
||||
function isTupleLikeType(type: Type): boolean {
|
||||
@@ -10905,9 +10906,10 @@ namespace ts {
|
||||
// Because the anyFunctionType is internal, it should not be exposed to the user by adding
|
||||
// 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.
|
||||
if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType) {
|
||||
// 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) {
|
||||
return;
|
||||
}
|
||||
const inference = getInferenceInfoForType(target);
|
||||
@@ -13948,7 +13950,7 @@ namespace ts {
|
||||
}
|
||||
return createArrayType(elementTypes.length ?
|
||||
getUnionType(elementTypes, /*subtypeReduction*/ true) :
|
||||
strictNullChecks ? neverType : undefinedWideningType);
|
||||
strictNullChecks ? implicitNeverType : undefinedWideningType);
|
||||
}
|
||||
|
||||
function isNumericName(name: DeclarationName): boolean {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//// [neverInference.ts]
|
||||
declare function f<T>(x: T[]): T;
|
||||
|
||||
let neverArray: never[] = [];
|
||||
|
||||
let a1 = f([]); // {}
|
||||
let a2 = f(neverArray); // never
|
||||
|
||||
// Repro from #19576
|
||||
|
||||
type Comparator<T> = (x: T, y: T) => number;
|
||||
|
||||
interface LinkedList<T> {
|
||||
comparator: Comparator<T>,
|
||||
nodes: Node<T>
|
||||
}
|
||||
|
||||
type Node<T> = { value: T, next: Node<T> } | null
|
||||
|
||||
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);
|
||||
|
||||
|
||||
//// [neverInference.js]
|
||||
"use strict";
|
||||
var neverArray = [];
|
||||
var a1 = f([]); // {}
|
||||
var a2 = f(neverArray); // never
|
||||
var list = mkList([], compareNumbers);
|
||||
@@ -0,0 +1,76 @@
|
||||
=== 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))
|
||||
|
||||
let neverArray: never[] = [];
|
||||
>neverArray : Symbol(neverArray, Decl(neverInference.ts, 2, 3))
|
||||
|
||||
let a1 = f([]); // {}
|
||||
>a1 : Symbol(a1, Decl(neverInference.ts, 4, 3))
|
||||
>f : Symbol(f, Decl(neverInference.ts, 0, 0))
|
||||
|
||||
let a2 = f(neverArray); // never
|
||||
>a2 : Symbol(a2, Decl(neverInference.ts, 5, 3))
|
||||
>f : Symbol(f, 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))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 9, 16))
|
||||
>x : Symbol(x, Decl(neverInference.ts, 9, 22))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 9, 16))
|
||||
>y : Symbol(y, Decl(neverInference.ts, 9, 27))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 9, 16))
|
||||
|
||||
interface LinkedList<T> {
|
||||
>LinkedList : Symbol(LinkedList, Decl(neverInference.ts, 9, 44))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 11, 21))
|
||||
|
||||
comparator: Comparator<T>,
|
||||
>comparator : Symbol(LinkedList.comparator, Decl(neverInference.ts, 11, 25))
|
||||
>Comparator : Symbol(Comparator, Decl(neverInference.ts, 5, 23))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 11, 21))
|
||||
|
||||
nodes: Node<T>
|
||||
>nodes : Symbol(LinkedList.nodes, Decl(neverInference.ts, 12, 30))
|
||||
>Node : Symbol(Node, Decl(neverInference.ts, 14, 1))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 11, 21))
|
||||
}
|
||||
|
||||
type Node<T> = { value: T, next: Node<T> } | null
|
||||
>Node : Symbol(Node, Decl(neverInference.ts, 14, 1))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 16, 10))
|
||||
>value : Symbol(value, Decl(neverInference.ts, 16, 16))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 16, 10))
|
||||
>next : Symbol(next, Decl(neverInference.ts, 16, 26))
|
||||
>Node : Symbol(Node, Decl(neverInference.ts, 14, 1))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 16, 10))
|
||||
|
||||
declare function compareNumbers(x: number, y: number): number;
|
||||
>compareNumbers : Symbol(compareNumbers, Decl(neverInference.ts, 16, 49))
|
||||
>x : Symbol(x, Decl(neverInference.ts, 18, 32))
|
||||
>y : Symbol(y, Decl(neverInference.ts, 18, 42))
|
||||
|
||||
declare function mkList<T>(items: T[], comparator: Comparator<T>): LinkedList<T>;
|
||||
>mkList : Symbol(mkList, Decl(neverInference.ts, 18, 62))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 19, 24))
|
||||
>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))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 19, 24))
|
||||
>LinkedList : Symbol(LinkedList, Decl(neverInference.ts, 9, 44))
|
||||
>T : Symbol(T, Decl(neverInference.ts, 19, 24))
|
||||
|
||||
const list: LinkedList<number> = mkList([], compareNumbers);
|
||||
>list : Symbol(list, Decl(neverInference.ts, 21, 5))
|
||||
>LinkedList : Symbol(LinkedList, Decl(neverInference.ts, 9, 44))
|
||||
>mkList : Symbol(mkList, Decl(neverInference.ts, 18, 62))
|
||||
>compareNumbers : Symbol(compareNumbers, Decl(neverInference.ts, 16, 49))
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
=== tests/cases/conformance/types/never/neverInference.ts ===
|
||||
declare function f<T>(x: T[]): T;
|
||||
>f : <T>(x: T[]) => T
|
||||
>T : T
|
||||
>x : T[]
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
let neverArray: never[] = [];
|
||||
>neverArray : never[]
|
||||
>[] : never[]
|
||||
|
||||
let a1 = f([]); // {}
|
||||
>a1 : {}
|
||||
>f([]) : {}
|
||||
>f : <T>(x: T[]) => T
|
||||
>[] : never[]
|
||||
|
||||
let a2 = f(neverArray); // never
|
||||
>a2 : never
|
||||
>f(neverArray) : never
|
||||
>f : <T>(x: T[]) => T
|
||||
>neverArray : never[]
|
||||
|
||||
// Repro from #19576
|
||||
|
||||
type Comparator<T> = (x: T, y: T) => number;
|
||||
>Comparator : Comparator<T>
|
||||
>T : T
|
||||
>x : T
|
||||
>T : T
|
||||
>y : T
|
||||
>T : T
|
||||
|
||||
interface LinkedList<T> {
|
||||
>LinkedList : LinkedList<T>
|
||||
>T : T
|
||||
|
||||
comparator: Comparator<T>,
|
||||
>comparator : Comparator<T>
|
||||
>Comparator : Comparator<T>
|
||||
>T : T
|
||||
|
||||
nodes: Node<T>
|
||||
>nodes : Node<T>
|
||||
>Node : Node<T>
|
||||
>T : T
|
||||
}
|
||||
|
||||
type Node<T> = { value: T, next: Node<T> } | null
|
||||
>Node : Node<T>
|
||||
>T : T
|
||||
>value : T
|
||||
>T : T
|
||||
>next : Node<T>
|
||||
>Node : Node<T>
|
||||
>T : T
|
||||
>null : null
|
||||
|
||||
declare function compareNumbers(x: number, y: number): number;
|
||||
>compareNumbers : (x: number, y: number) => number
|
||||
>x : number
|
||||
>y : number
|
||||
|
||||
declare function mkList<T>(items: T[], comparator: Comparator<T>): LinkedList<T>;
|
||||
>mkList : <T>(items: T[], comparator: Comparator<T>) => LinkedList<T>
|
||||
>T : T
|
||||
>items : T[]
|
||||
>T : T
|
||||
>comparator : Comparator<T>
|
||||
>Comparator : Comparator<T>
|
||||
>T : T
|
||||
>LinkedList : LinkedList<T>
|
||||
>T : T
|
||||
|
||||
const list: LinkedList<number> = mkList([], compareNumbers);
|
||||
>list : LinkedList<number>
|
||||
>LinkedList : LinkedList<T>
|
||||
>mkList([], compareNumbers) : LinkedList<number>
|
||||
>mkList : <T>(items: T[], comparator: Comparator<T>) => LinkedList<T>
|
||||
>[] : never[]
|
||||
>compareNumbers : (x: number, y: number) => number
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// @strict: true
|
||||
|
||||
declare function f<T>(x: T[]): T;
|
||||
|
||||
let neverArray: never[] = [];
|
||||
|
||||
let a1 = f([]); // {}
|
||||
let a2 = f(neverArray); // never
|
||||
|
||||
// Repro from #19576
|
||||
|
||||
type Comparator<T> = (x: T, y: T) => number;
|
||||
|
||||
interface LinkedList<T> {
|
||||
comparator: Comparator<T>,
|
||||
nodes: Node<T>
|
||||
}
|
||||
|
||||
type Node<T> = { value: T, next: Node<T> } | null
|
||||
|
||||
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);
|
||||
Reference in New Issue
Block a user