mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-24 04:30:53 -06:00
Use proper variances when inferring between type alias instantiations
This commit is contained in:
parent
c5c869f673
commit
08cd0b3700
@ -15171,11 +15171,7 @@ namespace ts {
|
||||
if (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
|
||||
// Source and target are types originating in the same generic type alias declaration.
|
||||
// Simply infer from source type arguments to target type arguments.
|
||||
const sourceTypes = source.aliasTypeArguments;
|
||||
const targetTypes = target.aliasTypeArguments!;
|
||||
for (let i = 0; i < sourceTypes.length; i++) {
|
||||
inferFromTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
inferFromTypeArguments(source.aliasTypeArguments, target.aliasTypeArguments!, getAliasVariances(source.aliasSymbol));
|
||||
return;
|
||||
}
|
||||
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union && !(source.flags & TypeFlags.EnumLiteral && target.flags & TypeFlags.EnumLiteral) ||
|
||||
@ -15281,18 +15277,7 @@ namespace ts {
|
||||
}
|
||||
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target) {
|
||||
// If source and target are references to the same generic type, infer from type arguments
|
||||
const sourceTypes = (<TypeReference>source).typeArguments || emptyArray;
|
||||
const targetTypes = (<TypeReference>target).typeArguments || emptyArray;
|
||||
const count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length;
|
||||
const variances = getVariances((<TypeReference>source).target);
|
||||
for (let i = 0; i < count; i++) {
|
||||
if (i < variances.length && (variances[i] & VarianceFlags.VarianceMask) === VarianceFlags.Contravariant) {
|
||||
inferFromContravariantTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
else {
|
||||
inferFromTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
}
|
||||
inferFromTypeArguments((<TypeReference>source).typeArguments || emptyArray, (<TypeReference>target).typeArguments || emptyArray, getVariances((<TypeReference>source).target));
|
||||
}
|
||||
else if (source.flags & TypeFlags.Index && target.flags & TypeFlags.Index) {
|
||||
contravariant = !contravariant;
|
||||
@ -15412,6 +15397,18 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function inferFromTypeArguments(sourceTypes: readonly Type[], targetTypes: readonly Type[], variances: readonly VarianceFlags[]) {
|
||||
const count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length;
|
||||
for (let i = 0; i < count; i++) {
|
||||
if (i < variances.length && (variances[i] & VarianceFlags.VarianceMask) === VarianceFlags.Contravariant) {
|
||||
inferFromContravariantTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
else {
|
||||
inferFromTypes(sourceTypes[i], targetTypes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function inferFromContravariantTypes(source: Type, target: Type) {
|
||||
if (strictFunctionTypes || priority & InferencePriority.AlwaysStrict) {
|
||||
contravariant = !contravariant;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user