Skip to content

Commit 3a74ec4

Browse files
authored
Disable constraint reduction in intersections created by constraint hoisting (#58403)
1 parent 7a38980 commit 3a74ec4

7 files changed

+266
-17
lines changed

src/compiler/checker.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ import {
446446
InterfaceType,
447447
InterfaceTypeWithDeclaredMembers,
448448
InternalSymbolName,
449+
IntersectionFlags,
449450
IntersectionType,
450451
IntersectionTypeNode,
451452
intrinsicTagNameToString,
@@ -14196,7 +14197,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1419614197
}
1419714198
}
1419814199
// The source types were normalized; ensure the result is normalized too.
14199-
return getNormalizedType(getIntersectionType(constraints), /*writing*/ false);
14200+
return getNormalizedType(getIntersectionType(constraints, IntersectionFlags.NoConstraintReduction), /*writing*/ false);
1420014201
}
1420114202
return undefined;
1420214203
}
@@ -17459,7 +17460,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1745917460
// a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
1746017461
// Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
1746117462
// for intersections of types with signatures can be deterministic.
17462-
function getIntersectionType(types: readonly Type[], aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[], noSupertypeReduction?: boolean): Type {
17463+
function getIntersectionType(types: readonly Type[], flags = IntersectionFlags.None, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
1746317464
const typeMembershipMap = new Map<string, Type>();
1746417465
const includes = addTypesToIntersection(typeMembershipMap, 0 as TypeFlags, types);
1746517466
const typeSet: Type[] = arrayFrom(typeMembershipMap.values());
@@ -17504,7 +17505,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1750417505
includes & TypeFlags.Void && includes & TypeFlags.Undefined ||
1750517506
includes & TypeFlags.IncludesEmptyObject && includes & TypeFlags.DefinitelyNonNullable
1750617507
) {
17507-
if (!noSupertypeReduction) removeRedundantSupertypes(typeSet, includes);
17508+
if (!(flags & IntersectionFlags.NoSupertypeReduction)) removeRedundantSupertypes(typeSet, includes);
1750817509
}
1750917510
if (includes & TypeFlags.IncludesMissingType) {
1751017511
typeSet[typeSet.indexOf(undefinedType)] = missingType;
@@ -17515,7 +17516,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1751517516
if (typeSet.length === 1) {
1751617517
return typeSet[0];
1751717518
}
17518-
if (typeSet.length === 2) {
17519+
if (typeSet.length === 2 && !(flags & IntersectionFlags.NoConstraintReduction)) {
1751917520
const typeVarIndex = typeSet[0].flags & TypeFlags.TypeVariable ? 0 : 1;
1752017521
const typeVariable = typeSet[typeVarIndex];
1752117522
const primitiveType = typeSet[1 - typeVarIndex];
@@ -17548,32 +17549,32 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1754817549
}
1754917550
}
1755017551
}
17551-
const id = getTypeListId(typeSet) + getAliasId(aliasSymbol, aliasTypeArguments);
17552+
const id = getTypeListId(typeSet) + (flags & IntersectionFlags.NoConstraintReduction ? "*" : getAliasId(aliasSymbol, aliasTypeArguments));
1755217553
let result = intersectionTypes.get(id);
1755317554
if (!result) {
1755417555
if (includes & TypeFlags.Union) {
1755517556
if (intersectUnionsOfPrimitiveTypes(typeSet)) {
1755617557
// When the intersection creates a reduced set (which might mean that *all* union types have
1755717558
// disappeared), we restart the operation to get a new set of combined flags. Once we have
1755817559
// reduced we'll never reduce again, so this occurs at most once.
17559-
result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
17560+
result = getIntersectionType(typeSet, flags, aliasSymbol, aliasTypeArguments);
1756017561
}
1756117562
else if (every(typeSet, t => !!(t.flags & TypeFlags.Union && (t as UnionType).types[0].flags & TypeFlags.Undefined))) {
1756217563
const containedUndefinedType = some(typeSet, containsMissingType) ? missingType : undefinedType;
1756317564
removeFromEach(typeSet, TypeFlags.Undefined);
17564-
result = getUnionType([getIntersectionType(typeSet), containedUndefinedType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
17565+
result = getUnionType([getIntersectionType(typeSet, flags), containedUndefinedType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
1756517566
}
1756617567
else if (every(typeSet, t => !!(t.flags & TypeFlags.Union && ((t as UnionType).types[0].flags & TypeFlags.Null || (t as UnionType).types[1].flags & TypeFlags.Null)))) {
1756717568
removeFromEach(typeSet, TypeFlags.Null);
17568-
result = getUnionType([getIntersectionType(typeSet), nullType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
17569+
result = getUnionType([getIntersectionType(typeSet, flags), nullType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
1756917570
}
1757017571
else if (typeSet.length >= 4) {
1757117572
// When we have four or more constituents, some of which are unions, we employ a "divide and conquer" strategy
1757217573
// where A & B & C & D is processed as (A & B) & (C & D). Since intersections of unions often produce far smaller
1757317574
// unions of intersections than the full cartesian product (due to some intersections becoming `never`), this can
1757417575
// dramatically reduce the overall work.
1757517576
const middle = Math.floor(typeSet.length / 2);
17576-
result = getIntersectionType([getIntersectionType(typeSet.slice(0, middle)), getIntersectionType(typeSet.slice(middle))], aliasSymbol, aliasTypeArguments);
17577+
result = getIntersectionType([getIntersectionType(typeSet.slice(0, middle), flags), getIntersectionType(typeSet.slice(middle), flags)], flags, aliasSymbol, aliasTypeArguments);
1757717578
}
1757817579
else {
1757917580
// We are attempting to construct a type of the form X & (A | B) & (C | D). Transform this into a type of
@@ -17582,7 +17583,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1758217583
if (!checkCrossProductUnion(typeSet)) {
1758317584
return errorType;
1758417585
}
17585-
const constituents = getCrossProductIntersections(typeSet);
17586+
const constituents = getCrossProductIntersections(typeSet, flags);
1758617587
// We attach a denormalized origin type when at least one constituent of the cross-product union is an
1758717588
// intersection (i.e. when the intersection didn't just reduce one or more unions to smaller unions) and
1758817589
// the denormalized origin has fewer constituents than the union itself.
@@ -17612,7 +17613,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1761217613
return true;
1761317614
}
1761417615

17615-
function getCrossProductIntersections(types: readonly Type[]) {
17616+
function getCrossProductIntersections(types: readonly Type[], flags: IntersectionFlags) {
1761617617
const count = getCrossProductUnionSize(types);
1761717618
const intersections: Type[] = [];
1761817619
for (let i = 0; i < count; i++) {
@@ -17626,7 +17627,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1762617627
n = Math.floor(n / length);
1762717628
}
1762817629
}
17629-
const t = getIntersectionType(constituents);
17630+
const t = getIntersectionType(constituents, flags);
1763017631
if (!(t.flags & TypeFlags.Never)) intersections.push(t);
1763117632
}
1763217633
return intersections;
@@ -17653,7 +17654,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1765317654
const emptyIndex = types.length === 2 ? types.indexOf(emptyTypeLiteralType) : -1;
1765417655
const t = emptyIndex >= 0 ? types[1 - emptyIndex] : unknownType;
1765517656
const noSupertypeReduction = !!(t.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.BigInt) || t.flags & TypeFlags.TemplateLiteral && isPatternLiteralType(t));
17656-
links.resolvedType = getIntersectionType(types, aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol), noSupertypeReduction);
17657+
links.resolvedType = getIntersectionType(types, noSupertypeReduction ? IntersectionFlags.NoSupertypeReduction : 0, aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
1765717658
}
1765817659
return links.resolvedType;
1765917660
}
@@ -18533,7 +18534,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1853318534
return undefined;
1853418535
}
1853518536
return accessFlags & AccessFlags.Writing
18536-
? getIntersectionType(propTypes, aliasSymbol, aliasTypeArguments)
18537+
? getIntersectionType(propTypes, IntersectionFlags.None, aliasSymbol, aliasTypeArguments)
1853718538
: getUnionType(propTypes, UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
1853818539
}
1853918540
return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, accessNode, accessFlags | AccessFlags.CacheSymbol | AccessFlags.ReportDeprecated);
@@ -19884,7 +19885,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1988419885
const newAliasSymbol = aliasSymbol || type.aliasSymbol;
1988519886
const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper);
1988619887
return flags & TypeFlags.Intersection || origin && origin.flags & TypeFlags.Intersection ?
19887-
getIntersectionType(newTypes, newAliasSymbol, newAliasTypeArguments) :
19888+
getIntersectionType(newTypes, IntersectionFlags.None, newAliasSymbol, newAliasTypeArguments) :
1988819889
getUnionType(newTypes, UnionReduction.Literal, newAliasSymbol, newAliasTypeArguments);
1988919890
}
1989019891
if (flags & TypeFlags.Index) {

src/compiler/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5379,6 +5379,13 @@ export const enum UnionReduction {
53795379
Subtype,
53805380
}
53815381

5382+
/** @internal */
5383+
export const enum IntersectionFlags {
5384+
None = 0,
5385+
NoSupertypeReduction = 1 << 0,
5386+
NoConstraintReduction = 1 << 1,
5387+
}
5388+
53825389
// dprint-ignore
53835390
/** @internal */
53845391
export const enum ContextFlags {
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
//// [tests/cases/compiler/intersectionConstraintReduction.ts] ////
2+
3+
=== intersectionConstraintReduction.ts ===
4+
type Test1<K1 extends keyof any, K2 extends keyof any> =
5+
>Test1 : Symbol(Test1, Decl(intersectionConstraintReduction.ts, 0, 0))
6+
>K1 : Symbol(K1, Decl(intersectionConstraintReduction.ts, 0, 11))
7+
>K2 : Symbol(K2, Decl(intersectionConstraintReduction.ts, 0, 32))
8+
9+
MustBeKey<Extract<K1, keyof any> & K1 & K2>;
10+
>MustBeKey : Symbol(MustBeKey, Decl(intersectionConstraintReduction.ts, 4, 48))
11+
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
12+
>K1 : Symbol(K1, Decl(intersectionConstraintReduction.ts, 0, 11))
13+
>K1 : Symbol(K1, Decl(intersectionConstraintReduction.ts, 0, 11))
14+
>K2 : Symbol(K2, Decl(intersectionConstraintReduction.ts, 0, 32))
15+
16+
type Test2<K1 extends keyof any, K2 extends keyof any> =
17+
>Test2 : Symbol(Test2, Decl(intersectionConstraintReduction.ts, 1, 48))
18+
>K1 : Symbol(K1, Decl(intersectionConstraintReduction.ts, 3, 11))
19+
>K2 : Symbol(K2, Decl(intersectionConstraintReduction.ts, 3, 32))
20+
21+
MustBeKey<K1 & K2 & Extract<K1, keyof any>>;
22+
>MustBeKey : Symbol(MustBeKey, Decl(intersectionConstraintReduction.ts, 4, 48))
23+
>K1 : Symbol(K1, Decl(intersectionConstraintReduction.ts, 3, 11))
24+
>K2 : Symbol(K2, Decl(intersectionConstraintReduction.ts, 3, 32))
25+
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
26+
>K1 : Symbol(K1, Decl(intersectionConstraintReduction.ts, 3, 11))
27+
28+
type MustBeKey<K extends keyof any> = K;
29+
>MustBeKey : Symbol(MustBeKey, Decl(intersectionConstraintReduction.ts, 4, 48))
30+
>K : Symbol(K, Decl(intersectionConstraintReduction.ts, 6, 15))
31+
>K : Symbol(K, Decl(intersectionConstraintReduction.ts, 6, 15))
32+
33+
// https://github.com/microsoft/TypeScript/issues/58370
34+
35+
type AnyKey = number | string | symbol;
36+
>AnyKey : Symbol(AnyKey, Decl(intersectionConstraintReduction.ts, 6, 40))
37+
38+
type ReturnTypeKeyof<Obj extends object> = Obj extends object
39+
>ReturnTypeKeyof : Symbol(ReturnTypeKeyof, Decl(intersectionConstraintReduction.ts, 10, 39))
40+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 12, 21))
41+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 12, 21))
42+
43+
? [keyof Obj] extends [never]
44+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 12, 21))
45+
46+
? never
47+
: { [Key in keyof Obj as string]-?: () => Key }[string]
48+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 15, 13))
49+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 12, 21))
50+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 15, 13))
51+
52+
: never;
53+
54+
type KeyIfSignatureOfObject<
55+
>KeyIfSignatureOfObject : Symbol(KeyIfSignatureOfObject, Decl(intersectionConstraintReduction.ts, 16, 12))
56+
57+
Obj extends object,
58+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 18, 28))
59+
60+
Key extends AnyKey,
61+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 19, 23))
62+
>AnyKey : Symbol(AnyKey, Decl(intersectionConstraintReduction.ts, 6, 40))
63+
64+
ReturnTypeKeys = ReturnTypeKeyof<Obj>,
65+
>ReturnTypeKeys : Symbol(ReturnTypeKeys, Decl(intersectionConstraintReduction.ts, 20, 23))
66+
>ReturnTypeKeyof : Symbol(ReturnTypeKeyof, Decl(intersectionConstraintReduction.ts, 10, 39))
67+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 18, 28))
68+
69+
> = ReturnTypeKeys extends () => Key ? ((() => Key) extends ReturnTypeKeys ? Key : never) : never;
70+
>ReturnTypeKeys : Symbol(ReturnTypeKeys, Decl(intersectionConstraintReduction.ts, 20, 23))
71+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 19, 23))
72+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 19, 23))
73+
>ReturnTypeKeys : Symbol(ReturnTypeKeys, Decl(intersectionConstraintReduction.ts, 20, 23))
74+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 19, 23))
75+
76+
export type Reduced1<Obj extends object, Key extends AnyKey, Value, ObjKeys extends keyof Obj = keyof Obj> =
77+
>Reduced1 : Symbol(Reduced1, Decl(intersectionConstraintReduction.ts, 22, 98))
78+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 24, 21))
79+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 24, 40))
80+
>AnyKey : Symbol(AnyKey, Decl(intersectionConstraintReduction.ts, 6, 40))
81+
>Value : Symbol(Value, Decl(intersectionConstraintReduction.ts, 24, 60))
82+
>ObjKeys : Symbol(ObjKeys, Decl(intersectionConstraintReduction.ts, 24, 67))
83+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 24, 21))
84+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 24, 21))
85+
86+
Key extends KeyIfSignatureOfObject<Obj, Key>
87+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 24, 40))
88+
>KeyIfSignatureOfObject : Symbol(KeyIfSignatureOfObject, Decl(intersectionConstraintReduction.ts, 16, 12))
89+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 24, 21))
90+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 24, 40))
91+
92+
? Key extends ObjKeys
93+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 24, 40))
94+
>ObjKeys : Symbol(ObjKeys, Decl(intersectionConstraintReduction.ts, 24, 67))
95+
96+
? { [K in Key]: Value }
97+
>K : Symbol(K, Decl(intersectionConstraintReduction.ts, 27, 17))
98+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 24, 40))
99+
>Value : Symbol(Value, Decl(intersectionConstraintReduction.ts, 24, 60))
100+
101+
: never
102+
: never;
103+
104+
export type Reduced2<Obj extends object, Key extends AnyKey, Value, ObjKeys extends keyof Obj = keyof Obj> =
105+
>Reduced2 : Symbol(Reduced2, Decl(intersectionConstraintReduction.ts, 29, 16))
106+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 31, 21))
107+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 31, 40))
108+
>AnyKey : Symbol(AnyKey, Decl(intersectionConstraintReduction.ts, 6, 40))
109+
>Value : Symbol(Value, Decl(intersectionConstraintReduction.ts, 31, 60))
110+
>ObjKeys : Symbol(ObjKeys, Decl(intersectionConstraintReduction.ts, 31, 67))
111+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 31, 21))
112+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 31, 21))
113+
114+
Key extends AnyKey
115+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 31, 40))
116+
>AnyKey : Symbol(AnyKey, Decl(intersectionConstraintReduction.ts, 6, 40))
117+
118+
? Key extends KeyIfSignatureOfObject<Obj, Key>
119+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 31, 40))
120+
>KeyIfSignatureOfObject : Symbol(KeyIfSignatureOfObject, Decl(intersectionConstraintReduction.ts, 16, 12))
121+
>Obj : Symbol(Obj, Decl(intersectionConstraintReduction.ts, 31, 21))
122+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 31, 40))
123+
124+
? Key extends ObjKeys
125+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 31, 40))
126+
>ObjKeys : Symbol(ObjKeys, Decl(intersectionConstraintReduction.ts, 31, 67))
127+
128+
? { [K in Key]: Value }
129+
>K : Symbol(K, Decl(intersectionConstraintReduction.ts, 35, 20))
130+
>Key : Symbol(Key, Decl(intersectionConstraintReduction.ts, 31, 40))
131+
>Value : Symbol(Value, Decl(intersectionConstraintReduction.ts, 31, 60))
132+
133+
: never
134+
: never
135+
: never;
136+
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//// [tests/cases/compiler/intersectionConstraintReduction.ts] ////
2+
3+
=== intersectionConstraintReduction.ts ===
4+
type Test1<K1 extends keyof any, K2 extends keyof any> =
5+
>Test1 : Extract<K1, string | number | symbol> & K1 & K2
6+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7+
8+
MustBeKey<Extract<K1, keyof any> & K1 & K2>;
9+
10+
type Test2<K1 extends keyof any, K2 extends keyof any> =
11+
>Test2 : K1 & K2 & Extract<K1, string | number | symbol>
12+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13+
14+
MustBeKey<K1 & K2 & Extract<K1, keyof any>>;
15+
16+
type MustBeKey<K extends keyof any> = K;
17+
>MustBeKey : K
18+
> : ^
19+
20+
// https://github.com/microsoft/TypeScript/issues/58370
21+
22+
type AnyKey = number | string | symbol;
23+
>AnyKey : AnyKey
24+
> : ^^^^^^
25+
26+
type ReturnTypeKeyof<Obj extends object> = Obj extends object
27+
>ReturnTypeKeyof : ReturnTypeKeyof<Obj>
28+
> : ^^^^^^^^^^^^^^^^^^^^
29+
30+
? [keyof Obj] extends [never]
31+
? never
32+
: { [Key in keyof Obj as string]-?: () => Key }[string]
33+
: never;
34+
35+
type KeyIfSignatureOfObject<
36+
>KeyIfSignatureOfObject : KeyIfSignatureOfObject<Obj, Key, ReturnTypeKeys>
37+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38+
39+
Obj extends object,
40+
Key extends AnyKey,
41+
ReturnTypeKeys = ReturnTypeKeyof<Obj>,
42+
> = ReturnTypeKeys extends () => Key ? ((() => Key) extends ReturnTypeKeys ? Key : never) : never;
43+
44+
export type Reduced1<Obj extends object, Key extends AnyKey, Value, ObjKeys extends keyof Obj = keyof Obj> =
45+
>Reduced1 : Reduced1<Obj, Key, Value, ObjKeys>
46+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
47+
48+
Key extends KeyIfSignatureOfObject<Obj, Key>
49+
? Key extends ObjKeys
50+
? { [K in Key]: Value }
51+
: never
52+
: never;
53+
54+
export type Reduced2<Obj extends object, Key extends AnyKey, Value, ObjKeys extends keyof Obj = keyof Obj> =
55+
>Reduced2 : Reduced2<Obj, Key, Value, ObjKeys>
56+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
57+
58+
Key extends AnyKey
59+
? Key extends KeyIfSignatureOfObject<Obj, Key>
60+
? Key extends ObjKeys
61+
? { [K in Key]: Value }
62+
: never
63+
: never
64+
: never;
65+

tests/baselines/reference/intersectionsOfLargeUnions.types

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//// [tests/cases/compiler/intersectionsOfLargeUnions.ts] ////
22

33
=== Performance Stats ===
4-
Strict subtype cache: 1,000
54
Assignability cache: 1,000
65
Type Count: 2,500
76

tests/baselines/reference/intersectionsOfLargeUnions2.types

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//// [tests/cases/compiler/intersectionsOfLargeUnions2.ts] ////
22

33
=== Performance Stats ===
4-
Strict subtype cache: 1,000
54
Assignability cache: 1,000
65
Type Count: 2,500
76

0 commit comments

Comments
 (0)