mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Remove type inference for spread types
This commit is contained in:
parent
f9fe01a6e3
commit
18c692a429
@ -8045,8 +8045,7 @@ namespace ts {
|
||||
return !!(type.flags & TypeFlags.TypeParameter ||
|
||||
type.flags & TypeFlags.Reference && forEach((<TypeReference>type).typeArguments, couldContainTypeParameters) ||
|
||||
type.flags & TypeFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) ||
|
||||
type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeParameters(<UnionOrIntersectionType>type) ||
|
||||
type.flags & TypeFlags.Spread && couldSpreadContainTypeParameters(type as SpreadType));
|
||||
type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeParameters(<UnionOrIntersectionType>type));
|
||||
}
|
||||
|
||||
function couldUnionOrIntersectionContainTypeParameters(type: UnionOrIntersectionType): boolean {
|
||||
@ -8056,11 +8055,6 @@ namespace ts {
|
||||
return type.couldContainTypeParameters;
|
||||
}
|
||||
|
||||
function couldSpreadContainTypeParameters(type: SpreadType): boolean {
|
||||
return !!(type.right.flags & TypeFlags.TypeParameter ||
|
||||
type.left.flags & TypeFlags.Spread && (type.left as SpreadType).right.flags & TypeFlags.TypeParameter);
|
||||
}
|
||||
|
||||
function isTypeParameterAtTopLevel(type: Type, typeParameter: TypeParameter): boolean {
|
||||
return type === typeParameter || type.flags & TypeFlags.UnionOrIntersection && forEach((<UnionOrIntersectionType>type).types, t => isTypeParameterAtTopLevel(t, typeParameter));
|
||||
}
|
||||
@ -8124,16 +8118,6 @@ namespace ts {
|
||||
target = removeTypesFromUnionOrIntersection(<UnionOrIntersectionType>target, matchingTypes);
|
||||
}
|
||||
}
|
||||
if (source.flags & TypeFlags.Spread && target.flags & TypeFlags.Spread) {
|
||||
// only the last type parameter is a valid inference site,
|
||||
// and only if not followed by object literal properties.
|
||||
if ((source as SpreadType).right.flags & TypeFlags.TypeParameter &&
|
||||
(target as SpreadType).right.flags & TypeFlags.TypeParameter) {
|
||||
inferFromTypes((source as SpreadType).right, (target as SpreadType).right);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
if (target.flags & TypeFlags.TypeParameter) {
|
||||
// If target is a type parameter, make an inference, unless the source type contains
|
||||
// the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
|
||||
@ -8210,59 +8194,33 @@ namespace ts {
|
||||
else {
|
||||
source = getApparentType(source);
|
||||
if (source.flags & TypeFlags.ObjectType) {
|
||||
if (target.flags & TypeFlags.Spread) {
|
||||
// with an object type as source, a spread target infers to its last type parameter it
|
||||
// contains, after removing any properties from a object type that precedes the type parameter
|
||||
// Note that the call to `typeDifference` creates a new anonymous type.
|
||||
const spread = target as SpreadType;
|
||||
const parameter = spread.right.flags & TypeFlags.TypeParameter ? spread.right : (spread.left as SpreadType).right;
|
||||
const object = spread.right.flags & TypeFlags.TypeParameter ? emptyObjectType : spread.right as ResolvedType;
|
||||
inferFromTypes(getTypeDifference(source, object), parameter);
|
||||
target = object;
|
||||
if (isInProcess(source, target)) {
|
||||
return;
|
||||
}
|
||||
inferFromStructure(source, target);
|
||||
if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) {
|
||||
return;
|
||||
}
|
||||
const key = source.id + "," + target.id;
|
||||
if (visited[key]) {
|
||||
return;
|
||||
}
|
||||
visited[key] = true;
|
||||
if (depth === 0) {
|
||||
sourceStack = [];
|
||||
targetStack = [];
|
||||
}
|
||||
sourceStack[depth] = source;
|
||||
targetStack[depth] = target;
|
||||
depth++;
|
||||
inferFromProperties(source, target);
|
||||
inferFromSignatures(source, target, SignatureKind.Call);
|
||||
inferFromSignatures(source, target, SignatureKind.Construct);
|
||||
inferFromIndexTypes(source, target);
|
||||
depth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function inferFromStructure(source: Type, target: Type) {
|
||||
if (isInProcess(source, target)) {
|
||||
return;
|
||||
}
|
||||
if (isDeeplyNestedGeneric(source, sourceStack, depth) && isDeeplyNestedGeneric(target, targetStack, depth)) {
|
||||
return;
|
||||
}
|
||||
const key = source.id + "," + target.id;
|
||||
if (visited[key]) {
|
||||
return;
|
||||
}
|
||||
visited[key] = true;
|
||||
if (depth === 0) {
|
||||
sourceStack = [];
|
||||
targetStack = [];
|
||||
}
|
||||
sourceStack[depth] = source;
|
||||
targetStack[depth] = target;
|
||||
depth++;
|
||||
inferFromProperties(source, target);
|
||||
inferFromSignatures(source, target, SignatureKind.Call);
|
||||
inferFromSignatures(source, target, SignatureKind.Construct);
|
||||
inferFromIndexTypes(source, target);
|
||||
depth--;
|
||||
}
|
||||
|
||||
function getTypeDifference(type: ObjectType, diff: ResolvedType): ResolvedType {
|
||||
const members = createMap<Symbol>();
|
||||
for (const prop of getPropertiesOfObjectType(type)) {
|
||||
if (!(prop.name in diff.members)) {
|
||||
members[prop.name] = prop;
|
||||
}
|
||||
}
|
||||
const stringIndexInfo = getIndexInfoOfType(diff, IndexKind.String) ? undefined : getIndexInfoOfType(type, IndexKind.String);
|
||||
const numberIndexInfo = getIndexInfoOfType(diff, IndexKind.Number) ? undefined : getIndexInfoOfType(type, IndexKind.Number);
|
||||
return createAnonymousType(type.symbol, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
}
|
||||
|
||||
function inferFromProperties(source: Type, target: Type) {
|
||||
const properties = getPropertiesOfObjectType(target);
|
||||
for (const targetProp of properties) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user