Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b100680

Browse filesBrowse files
authored
Fix for relating covered discriminants in unions (microsoft#39393)
2 parents 0c75021 + 8eba362 commit b100680
Copy full SHA for b100680

6 files changed

+104-4Lines changed: 104 additions & 4 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/checker.ts‎

Copy file name to clipboardExpand all lines: src/compiler/checker.ts
+15-1Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17279,7 +17279,11 @@ namespace ts {
1727917279
result &= signaturesRelatedTo(source, type, SignatureKind.Construct, /*reportStructuralErrors*/ false);
1728017280
if (result) {
1728117281
result &= indexTypesRelatedTo(source, type, IndexKind.String, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None);
17282-
if (result) {
17282+
// Comparing numeric index types when both `source` and `type` are tuples is unnecessary as the
17283+
// element types should be sufficiently covered by `propertiesRelatedTo`. It also causes problems
17284+
// with index type assignability as the types for the excluded discriminants are still included
17285+
// in the index type.
17286+
if (result && !(isTupleType(source) && isTupleType(type))) {
1728317287
result &= indexTypesRelatedTo(source, type, IndexKind.Number, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None);
1728417288
}
1728517289
}
@@ -17504,6 +17508,7 @@ namespace ts {
1750417508
for (let i = 0; i < maxArity; i++) {
1750517509
const targetFlags = i < targetArity ? target.target.elementFlags[i] : targetRestFlag;
1750617510
const sourceFlags = isTupleType(source) && i < sourceArity ? source.target.elementFlags[i] : sourceRestFlag;
17511+
let canExcludeDiscriminants = !!excludedProperties;
1750717512
if (sourceFlags && targetFlags) {
1750817513
if (targetFlags & ElementFlags.Variadic && !(sourceFlags & ElementFlags.Variadic) ||
1750917514
(sourceFlags & ElementFlags.Variadic && !(targetFlags & ElementFlags.Variable))) {
@@ -17520,6 +17525,15 @@ namespace ts {
1752017525
return Ternary.False;
1752117526
}
1752217527
}
17528+
// We can only exclude discriminant properties if we have not yet encountered a variable-length element.
17529+
if (canExcludeDiscriminants) {
17530+
if (sourceFlags & ElementFlags.Variable || targetFlags & ElementFlags.Variable) {
17531+
canExcludeDiscriminants = false;
17532+
}
17533+
if (canExcludeDiscriminants && excludedProperties?.has(("" + i) as __String)) {
17534+
continue;
17535+
}
17536+
}
1752317537
const sourceType = getTypeArguments(source)[Math.min(i, sourceArity - 1)];
1752417538
const targetType = getTypeArguments(target)[Math.min(i, targetArity - 1)];
1752517539
const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : targetType;
Collapse file

‎tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.errors.txt‎

Copy file name to clipboardExpand all lines: tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.errors.txt
+10-1Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,4 +221,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
221221
type: obj1.type
222222
};
223223
}
224-
}
224+
}
225+
226+
// https://github.com/microsoft/TypeScript/issues/39357
227+
namespace GH39357 {
228+
type A = ["a", number] | ["b", number] | ["c", string];
229+
type B = "a" | "b" | "c";
230+
declare const b: B;
231+
const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""];
232+
}
233+
Collapse file

‎tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.js‎

Copy file name to clipboardExpand all lines: tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.js
+15-1Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,16 @@ namespace GH20889 {
191191
type: obj1.type
192192
};
193193
}
194-
}
194+
}
195+
196+
// https://github.com/microsoft/TypeScript/issues/39357
197+
namespace GH39357 {
198+
type A = ["a", number] | ["b", number] | ["c", string];
199+
type B = "a" | "b" | "c";
200+
declare const b: B;
201+
const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""];
202+
}
203+
195204

196205
//// [assignmentCompatWithDiscriminatedUnion.js]
197206
// see 'typeRelatedToDiscriminatedType' in checker.ts:
@@ -289,3 +298,8 @@ var GH20889;
289298
};
290299
}
291300
})(GH20889 || (GH20889 = {}));
301+
// https://github.com/microsoft/TypeScript/issues/39357
302+
var GH39357;
303+
(function (GH39357) {
304+
var a = b === "a" || b === "b" ? [b, 1] : ["c", ""];
305+
})(GH39357 || (GH39357 = {}));
Collapse file

‎tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.symbols‎

Copy file name to clipboardExpand all lines: tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.symbols
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,3 +492,26 @@ namespace GH20889 {
492492
};
493493
}
494494
}
495+
496+
// https://github.com/microsoft/TypeScript/issues/39357
497+
namespace GH39357 {
498+
>GH39357 : Symbol(GH39357, Decl(assignmentCompatWithDiscriminatedUnion.ts, 192, 1))
499+
500+
type A = ["a", number] | ["b", number] | ["c", string];
501+
>A : Symbol(A, Decl(assignmentCompatWithDiscriminatedUnion.ts, 195, 19))
502+
503+
type B = "a" | "b" | "c";
504+
>B : Symbol(B, Decl(assignmentCompatWithDiscriminatedUnion.ts, 196, 59))
505+
506+
declare const b: B;
507+
>b : Symbol(b, Decl(assignmentCompatWithDiscriminatedUnion.ts, 198, 17))
508+
>B : Symbol(B, Decl(assignmentCompatWithDiscriminatedUnion.ts, 196, 59))
509+
510+
const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""];
511+
>a : Symbol(a, Decl(assignmentCompatWithDiscriminatedUnion.ts, 199, 9))
512+
>A : Symbol(A, Decl(assignmentCompatWithDiscriminatedUnion.ts, 195, 19))
513+
>b : Symbol(b, Decl(assignmentCompatWithDiscriminatedUnion.ts, 198, 17))
514+
>b : Symbol(b, Decl(assignmentCompatWithDiscriminatedUnion.ts, 198, 17))
515+
>b : Symbol(b, Decl(assignmentCompatWithDiscriminatedUnion.ts, 198, 17))
516+
}
517+
Collapse file

‎tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.types‎

Copy file name to clipboardExpand all lines: tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.types
+32Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,3 +464,35 @@ namespace GH20889 {
464464
};
465465
}
466466
}
467+
468+
// https://github.com/microsoft/TypeScript/issues/39357
469+
namespace GH39357 {
470+
>GH39357 : typeof GH39357
471+
472+
type A = ["a", number] | ["b", number] | ["c", string];
473+
>A : A
474+
475+
type B = "a" | "b" | "c";
476+
>B : "a" | "b" | "c"
477+
478+
declare const b: B;
479+
>b : "a" | "b" | "c"
480+
481+
const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""];
482+
>a : A
483+
>b === "a" || b === "b" ? [b, 1] : ["c", ""] : ["a" | "b", number] | ["c", string]
484+
>b === "a" || b === "b" : boolean
485+
>b === "a" : boolean
486+
>b : "a" | "b" | "c"
487+
>"a" : "a"
488+
>b === "b" : boolean
489+
>b : "b" | "c"
490+
>"b" : "b"
491+
>[b, 1] : ["a" | "b", number]
492+
>b : "a" | "b"
493+
>1 : 1
494+
>["c", ""] : ["c", string]
495+
>"c" : "c"
496+
>"" : ""
497+
}
498+
Collapse file

‎tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts‎

Copy file name to clipboardExpand all lines: tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts
+9-1Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,12 @@ namespace GH20889 {
190190
type: obj1.type
191191
};
192192
}
193-
}
193+
}
194+
195+
// https://github.com/microsoft/TypeScript/issues/39357
196+
namespace GH39357 {
197+
type A = ["a", number] | ["b", number] | ["c", string];
198+
type B = "a" | "b" | "c";
199+
declare const b: B;
200+
const a: A = b === "a" || b === "b" ? [b, 1] : ["c", ""];
201+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.