Fix for relating covered discriminants in unions (#39393)
This commit is contained in:
commit
b100680a3e
|
@ -17279,7 +17279,11 @@ namespace ts {
|
|||
result &= signaturesRelatedTo(source, type, SignatureKind.Construct, /*reportStructuralErrors*/ false);
|
||||
if (result) {
|
||||
result &= indexTypesRelatedTo(source, type, IndexKind.String, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None);
|
||||
if (result) {
|
||||
// Comparing numeric index types when both `source` and `type` are tuples is unnecessary as the
|
||||
// element types should be sufficiently covered by `propertiesRelatedTo`. It also causes problems
|
||||
// with index type assignability as the types for the excluded discriminants are still included
|
||||
// in the index type.
|
||||
if (result && !(isTupleType(source) && isTupleType(type))) {
|
||||
result &= indexTypesRelatedTo(source, type, IndexKind.Number, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None);
|
||||
}
|
||||
}
|
||||
|
@ -17504,6 +17508,7 @@ namespace ts {
|
|||
for (let i = 0; i < maxArity; i++) {
|
||||
const targetFlags = i < targetArity ? target.target.elementFlags[i] : targetRestFlag;
|
||||
const sourceFlags = isTupleType(source) && i < sourceArity ? source.target.elementFlags[i] : sourceRestFlag;
|
||||
let canExcludeDiscriminants = !!excludedProperties;
|
||||
if (sourceFlags && targetFlags) {
|
||||
if (targetFlags & ElementFlags.Variadic && !(sourceFlags & ElementFlags.Variadic) ||
|
||||
(sourceFlags & ElementFlags.Variadic && !(targetFlags & ElementFlags.Variable))) {
|
||||
|
@ -17520,6 +17525,15 @@ namespace ts {
|
|||
return Ternary.False;
|
||||
}
|
||||
}
|
||||
// We can only exclude discriminant properties if we have not yet encountered a variable-length element.
|
||||
if (canExcludeDiscriminants) {
|
||||
if (sourceFlags & ElementFlags.Variable || targetFlags & ElementFlags.Variable) {
|
||||
canExcludeDiscriminants = false;
|
||||
}
|
||||
if (canExcludeDiscriminants && excludedProperties?.has(("" + i) as __String)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const sourceType = getTypeArguments(source)[Math.min(i, sourceArity - 1)];
|
||||
const targetType = getTypeArguments(target)[Math.min(i, targetArity - 1)];
|
||||
const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : targetType;
|
||||
|
|
|
@ -221,4 +221,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
|
|||
type: obj1.type
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/39357
|
||||
namespace GH39357 {
|
||||
type A = ["a", number] | ["b", number] | ["c", string];
|
||||
type B = "a" | "b" | "c";
|
||||
declare const b: B;
|
||||
const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""];
|
||||
}
|
||||
|
|
@ -191,7 +191,16 @@ namespace GH20889 {
|
|||
type: obj1.type
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/39357
|
||||
namespace GH39357 {
|
||||
type A = ["a", number] | ["b", number] | ["c", string];
|
||||
type B = "a" | "b" | "c";
|
||||
declare const b: B;
|
||||
const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""];
|
||||
}
|
||||
|
||||
|
||||
//// [assignmentCompatWithDiscriminatedUnion.js]
|
||||
// see 'typeRelatedToDiscriminatedType' in checker.ts:
|
||||
|
@ -289,3 +298,8 @@ var GH20889;
|
|||
};
|
||||
}
|
||||
})(GH20889 || (GH20889 = {}));
|
||||
// https://github.com/microsoft/TypeScript/issues/39357
|
||||
var GH39357;
|
||||
(function (GH39357) {
|
||||
var a = b === "a" || b === "b" ? [b, 1] : ["c", ""];
|
||||
})(GH39357 || (GH39357 = {}));
|
||||
|
|
|
@ -492,3 +492,26 @@ namespace GH20889 {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/39357
|
||||
namespace GH39357 {
|
||||
>GH39357 : Symbol(GH39357, Decl(assignmentCompatWithDiscriminatedUnion.ts, 192, 1))
|
||||
|
||||
type A = ["a", number] | ["b", number] | ["c", string];
|
||||
>A : Symbol(A, Decl(assignmentCompatWithDiscriminatedUnion.ts, 195, 19))
|
||||
|
||||
type B = "a" | "b" | "c";
|
||||
>B : Symbol(B, Decl(assignmentCompatWithDiscriminatedUnion.ts, 196, 59))
|
||||
|
||||
declare const b: B;
|
||||
>b : Symbol(b, Decl(assignmentCompatWithDiscriminatedUnion.ts, 198, 17))
|
||||
>B : Symbol(B, Decl(assignmentCompatWithDiscriminatedUnion.ts, 196, 59))
|
||||
|
||||
const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""];
|
||||
>a : Symbol(a, Decl(assignmentCompatWithDiscriminatedUnion.ts, 199, 9))
|
||||
>A : Symbol(A, Decl(assignmentCompatWithDiscriminatedUnion.ts, 195, 19))
|
||||
>b : Symbol(b, Decl(assignmentCompatWithDiscriminatedUnion.ts, 198, 17))
|
||||
>b : Symbol(b, Decl(assignmentCompatWithDiscriminatedUnion.ts, 198, 17))
|
||||
>b : Symbol(b, Decl(assignmentCompatWithDiscriminatedUnion.ts, 198, 17))
|
||||
}
|
||||
|
||||
|
|
|
@ -464,3 +464,35 @@ namespace GH20889 {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/39357
|
||||
namespace GH39357 {
|
||||
>GH39357 : typeof GH39357
|
||||
|
||||
type A = ["a", number] | ["b", number] | ["c", string];
|
||||
>A : A
|
||||
|
||||
type B = "a" | "b" | "c";
|
||||
>B : "a" | "b" | "c"
|
||||
|
||||
declare const b: B;
|
||||
>b : "a" | "b" | "c"
|
||||
|
||||
const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""];
|
||||
>a : A
|
||||
>b === "a" || b === "b" ? [b, 1] : ["c", ""] : ["a" | "b", number] | ["c", string]
|
||||
>b === "a" || b === "b" : boolean
|
||||
>b === "a" : boolean
|
||||
>b : "a" | "b" | "c"
|
||||
>"a" : "a"
|
||||
>b === "b" : boolean
|
||||
>b : "b" | "c"
|
||||
>"b" : "b"
|
||||
>[b, 1] : ["a" | "b", number]
|
||||
>b : "a" | "b"
|
||||
>1 : 1
|
||||
>["c", ""] : ["c", string]
|
||||
>"c" : "c"
|
||||
>"" : ""
|
||||
}
|
||||
|
||||
|
|
|
@ -190,4 +190,12 @@ namespace GH20889 {
|
|||
type: obj1.type
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/39357
|
||||
namespace GH39357 {
|
||||
type A = ["a", number] | ["b", number] | ["c", string];
|
||||
type B = "a" | "b" | "c";
|
||||
declare const b: B;
|
||||
const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue