Skip to content

Commit e3f6b43

Browse files
committed
discard never aggregate inferences
1 parent 15eda09 commit e3f6b43

File tree

4 files changed

+366
-5
lines changed

4 files changed

+366
-5
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26447,7 +26447,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2644726447
}
2644826448
if (inference.indexes) {
2644926449
const eraseSelfMapper = makeArrayTypeMapper([constraint.type, typeParameter], [allKeysAllKeysUnknownType, stringNumberSymbolType]);
26450-
return instantiateType(getIntersectionType(inference.indexes), eraseSelfMapper);
26450+
const aggregateInference = instantiateType(getIntersectionType(inference.indexes), eraseSelfMapper);
26451+
if (!(getReducedType(aggregateInference).flags & TypeFlags.Never)) {
26452+
return aggregateInference;
26453+
}
2645126454
}
2645226455
return unknownType;
2645326456
}
@@ -26900,8 +26903,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2690026903
return;
2690126904
}
2690226905
if (!inference.isFixed) {
26903-
// Instantiates instance of `type PartialInference<T, Keys extends string> = ({[K in Keys]: {[K1 in K]: T}})[Keys];`
26904-
// Where `T` is `source` and `Keys` is `target.indexType`
2690526906
const partialInferenceTypeSymbol = getGlobalPartialInferenceSymbol();
2690626907
if (partialInferenceTypeSymbol) {
2690726908
if ((target as IndexedAccessType).indexType.flags & TypeFlags.Instantiable) {
@@ -26911,6 +26912,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2691126912
}
2691226913
}
2691326914
else {
26915+
// Instantiates instance of `type PartialInference<T, Keys extends PropertyKey> = ({[K in Keys]: {[K1 in K]: T}})[Keys];`
26916+
// Where `T` is `source` and `Keys` is `target.indexType`
2691426917
inference.indexes = append(inference.indexes, getTypeAliasInstantiation(partialInferenceTypeSymbol, [source, (target as IndexedAccessType).indexType]));
2691526918
}
2691626919
}
@@ -27591,9 +27594,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2759127594
}
2759227595
else if (inference.indexes) {
2759327596
const eraseSelfMapper = makeUnaryTypeMapper(inference.typeParameter, allKeysUnknownType);
27594-
let aggregateInference = instantiateType(getIntersectionType(inference.indexes), mergeTypeMappers(eraseSelfMapper, context.nonFixingMapper));
27597+
let aggregateInference: Type | undefined = instantiateType(getIntersectionType(inference.indexes), mergeTypeMappers(eraseSelfMapper, context.nonFixingMapper));
27598+
if (getReducedType(aggregateInference).flags & TypeFlags.Never) {
27599+
// `never` inference isn't that useful of an inference given its assignable to every other type
27600+
aggregateInference = undefined;
27601+
}
2759527602
const constraint = getConstraintOfTypeParameter(inference.typeParameter);
27596-
if (constraint) {
27603+
if (aggregateInference && constraint) {
2759727604
const instantiatedConstraint = instantiateType(constraint, context.nonFixingMapper);
2759827605
if (instantiatedConstraint.flags & TypeFlags.Union && !context.compareTypes(aggregateInference, getTypeWithThisArgument(instantiatedConstraint, aggregateInference))) {
2759927606
const discriminantProps = findDiscriminantProperties(getPropertiesOfType(aggregateInference), instantiatedConstraint);
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//// [tests/cases/compiler/indexAccessCombinedInference2.ts] ////
2+
3+
=== indexAccessCombinedInference2.ts ===
4+
type TLArrowShape = {
5+
>TLArrowShape : Symbol(TLArrowShape, Decl(indexAccessCombinedInference2.ts, 0, 0))
6+
7+
type: "arrow";
8+
>type : Symbol(type, Decl(indexAccessCombinedInference2.ts, 0, 21))
9+
10+
id: string;
11+
>id : Symbol(id, Decl(indexAccessCombinedInference2.ts, 1, 16))
12+
13+
x: number;
14+
>x : Symbol(x, Decl(indexAccessCombinedInference2.ts, 2, 13))
15+
16+
y: number;
17+
>y : Symbol(y, Decl(indexAccessCombinedInference2.ts, 3, 12))
18+
19+
props: {
20+
>props : Symbol(props, Decl(indexAccessCombinedInference2.ts, 4, 12))
21+
22+
dir: 1 | -1;
23+
>dir : Symbol(dir, Decl(indexAccessCombinedInference2.ts, 5, 10))
24+
25+
};
26+
};
27+
28+
type NodeShape = {
29+
>NodeShape : Symbol(NodeShape, Decl(indexAccessCombinedInference2.ts, 8, 2))
30+
31+
type: "node";
32+
>type : Symbol(type, Decl(indexAccessCombinedInference2.ts, 10, 18))
33+
34+
id: string;
35+
>id : Symbol(id, Decl(indexAccessCombinedInference2.ts, 11, 15))
36+
37+
x: number;
38+
>x : Symbol(x, Decl(indexAccessCombinedInference2.ts, 12, 13))
39+
40+
y: number;
41+
>y : Symbol(y, Decl(indexAccessCombinedInference2.ts, 13, 12))
42+
43+
props: {
44+
>props : Symbol(props, Decl(indexAccessCombinedInference2.ts, 14, 12))
45+
46+
nodeType: string;
47+
>nodeType : Symbol(nodeType, Decl(indexAccessCombinedInference2.ts, 15, 10))
48+
49+
};
50+
};
51+
52+
type TLShape = TLArrowShape | NodeShape;
53+
>TLShape : Symbol(TLShape, Decl(indexAccessCombinedInference2.ts, 18, 2))
54+
>TLArrowShape : Symbol(TLArrowShape, Decl(indexAccessCombinedInference2.ts, 0, 0))
55+
>NodeShape : Symbol(NodeShape, Decl(indexAccessCombinedInference2.ts, 8, 2))
56+
57+
export type TLShapePartial<T extends TLShape = TLShape> = T extends T
58+
>TLShapePartial : Symbol(TLShapePartial, Decl(indexAccessCombinedInference2.ts, 20, 40))
59+
>T : Symbol(T, Decl(indexAccessCombinedInference2.ts, 22, 27))
60+
>TLShape : Symbol(TLShape, Decl(indexAccessCombinedInference2.ts, 18, 2))
61+
>TLShape : Symbol(TLShape, Decl(indexAccessCombinedInference2.ts, 18, 2))
62+
>T : Symbol(T, Decl(indexAccessCombinedInference2.ts, 22, 27))
63+
>T : Symbol(T, Decl(indexAccessCombinedInference2.ts, 22, 27))
64+
65+
? {
66+
id: string;
67+
>id : Symbol(id, Decl(indexAccessCombinedInference2.ts, 23, 5))
68+
69+
type: T["type"];
70+
>type : Symbol(type, Decl(indexAccessCombinedInference2.ts, 24, 17))
71+
>T : Symbol(T, Decl(indexAccessCombinedInference2.ts, 22, 27))
72+
73+
props?: Partial<T["props"]>;
74+
>props : Symbol(props, Decl(indexAccessCombinedInference2.ts, 25, 22))
75+
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
76+
>T : Symbol(T, Decl(indexAccessCombinedInference2.ts, 22, 27))
77+
78+
} & Partial<Omit<T, "type" | "id" | "props">>
79+
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
80+
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
81+
>T : Symbol(T, Decl(indexAccessCombinedInference2.ts, 22, 27))
82+
83+
: never;
84+
85+
declare class Editor {
86+
>Editor : Symbol(Editor, Decl(indexAccessCombinedInference2.ts, 28, 10))
87+
88+
updateShape<T extends TLShape = TLShape>(
89+
>updateShape : Symbol(Editor.updateShape, Decl(indexAccessCombinedInference2.ts, 30, 22))
90+
>T : Symbol(T, Decl(indexAccessCombinedInference2.ts, 31, 14))
91+
>TLShape : Symbol(TLShape, Decl(indexAccessCombinedInference2.ts, 18, 2))
92+
>TLShape : Symbol(TLShape, Decl(indexAccessCombinedInference2.ts, 18, 2))
93+
94+
partial: TLShapePartial<T> | null | undefined,
95+
>partial : Symbol(partial, Decl(indexAccessCombinedInference2.ts, 31, 43))
96+
>TLShapePartial : Symbol(TLShapePartial, Decl(indexAccessCombinedInference2.ts, 20, 40))
97+
>T : Symbol(T, Decl(indexAccessCombinedInference2.ts, 31, 14))
98+
99+
): T;
100+
>T : Symbol(T, Decl(indexAccessCombinedInference2.ts, 31, 14))
101+
}
102+
103+
declare const x: number;
104+
>x : Symbol(x, Decl(indexAccessCombinedInference2.ts, 36, 13))
105+
106+
declare const y: number;
107+
>y : Symbol(y, Decl(indexAccessCombinedInference2.ts, 37, 13))
108+
109+
declare const editor: Editor;
110+
>editor : Symbol(editor, Decl(indexAccessCombinedInference2.ts, 38, 13))
111+
>Editor : Symbol(Editor, Decl(indexAccessCombinedInference2.ts, 28, 10))
112+
113+
declare const node1: NodeShape;
114+
>node1 : Symbol(node1, Decl(indexAccessCombinedInference2.ts, 40, 13))
115+
>NodeShape : Symbol(NodeShape, Decl(indexAccessCombinedInference2.ts, 8, 2))
116+
117+
const node2 = editor.updateShape({ ...node1, x, y });
118+
>node2 : Symbol(node2, Decl(indexAccessCombinedInference2.ts, 41, 5))
119+
>editor.updateShape : Symbol(Editor.updateShape, Decl(indexAccessCombinedInference2.ts, 30, 22))
120+
>editor : Symbol(editor, Decl(indexAccessCombinedInference2.ts, 38, 13))
121+
>updateShape : Symbol(Editor.updateShape, Decl(indexAccessCombinedInference2.ts, 30, 22))
122+
>node1 : Symbol(node1, Decl(indexAccessCombinedInference2.ts, 40, 13))
123+
>x : Symbol(x, Decl(indexAccessCombinedInference2.ts, 41, 44))
124+
>y : Symbol(y, Decl(indexAccessCombinedInference2.ts, 41, 47))
125+
126+
declare const shape1: TLShape;
127+
>shape1 : Symbol(shape1, Decl(indexAccessCombinedInference2.ts, 43, 13))
128+
>TLShape : Symbol(TLShape, Decl(indexAccessCombinedInference2.ts, 18, 2))
129+
130+
const shape2 = editor.updateShape({ ...shape1, x, y });
131+
>shape2 : Symbol(shape2, Decl(indexAccessCombinedInference2.ts, 44, 5))
132+
>editor.updateShape : Symbol(Editor.updateShape, Decl(indexAccessCombinedInference2.ts, 30, 22))
133+
>editor : Symbol(editor, Decl(indexAccessCombinedInference2.ts, 38, 13))
134+
>updateShape : Symbol(Editor.updateShape, Decl(indexAccessCombinedInference2.ts, 30, 22))
135+
>shape1 : Symbol(shape1, Decl(indexAccessCombinedInference2.ts, 43, 13))
136+
>x : Symbol(x, Decl(indexAccessCombinedInference2.ts, 44, 46))
137+
>y : Symbol(y, Decl(indexAccessCombinedInference2.ts, 44, 49))
138+
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
//// [tests/cases/compiler/indexAccessCombinedInference2.ts] ////
2+
3+
=== indexAccessCombinedInference2.ts ===
4+
type TLArrowShape = {
5+
>TLArrowShape : TLArrowShape
6+
> : ^^^^^^^^^^^^
7+
8+
type: "arrow";
9+
>type : "arrow"
10+
> : ^^^^^^^
11+
12+
id: string;
13+
>id : string
14+
> : ^^^^^^
15+
16+
x: number;
17+
>x : number
18+
> : ^^^^^^
19+
20+
y: number;
21+
>y : number
22+
> : ^^^^^^
23+
24+
props: {
25+
>props : { dir: 1 | -1; }
26+
> : ^^^^^^^ ^^^
27+
28+
dir: 1 | -1;
29+
>dir : 1 | -1
30+
> : ^^^^^^
31+
>-1 : -1
32+
> : ^^
33+
>1 : 1
34+
> : ^
35+
36+
};
37+
};
38+
39+
type NodeShape = {
40+
>NodeShape : NodeShape
41+
> : ^^^^^^^^^
42+
43+
type: "node";
44+
>type : "node"
45+
> : ^^^^^^
46+
47+
id: string;
48+
>id : string
49+
> : ^^^^^^
50+
51+
x: number;
52+
>x : number
53+
> : ^^^^^^
54+
55+
y: number;
56+
>y : number
57+
> : ^^^^^^
58+
59+
props: {
60+
>props : { nodeType: string; }
61+
> : ^^^^^^^^^^^^ ^^^
62+
63+
nodeType: string;
64+
>nodeType : string
65+
> : ^^^^^^
66+
67+
};
68+
};
69+
70+
type TLShape = TLArrowShape | NodeShape;
71+
>TLShape : TLShape
72+
> : ^^^^^^^
73+
74+
export type TLShapePartial<T extends TLShape = TLShape> = T extends T
75+
>TLShapePartial : TLShapePartial<T>
76+
> : ^^^^^^^^^^^^^^^^^
77+
78+
? {
79+
id: string;
80+
>id : string
81+
> : ^^^^^^
82+
83+
type: T["type"];
84+
>type : T["type"]
85+
> : ^^^^^^^^^
86+
87+
props?: Partial<T["props"]>;
88+
>props : Partial<T["props"]> | undefined
89+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
90+
91+
} & Partial<Omit<T, "type" | "id" | "props">>
92+
: never;
93+
94+
declare class Editor {
95+
>Editor : Editor
96+
> : ^^^^^^
97+
98+
updateShape<T extends TLShape = TLShape>(
99+
>updateShape : <T extends TLShape = TLShape>(partial: TLShapePartial<T> | null | undefined) => T
100+
> : ^ ^^^^^^^^^ ^^^^^^^^^^^^ ^^ ^^^^^
101+
102+
partial: TLShapePartial<T> | null | undefined,
103+
>partial : TLShapePartial<T> | null | undefined
104+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
105+
106+
): T;
107+
}
108+
109+
declare const x: number;
110+
>x : number
111+
> : ^^^^^^
112+
113+
declare const y: number;
114+
>y : number
115+
> : ^^^^^^
116+
117+
declare const editor: Editor;
118+
>editor : Editor
119+
> : ^^^^^^
120+
121+
declare const node1: NodeShape;
122+
>node1 : NodeShape
123+
> : ^^^^^^^^^
124+
125+
const node2 = editor.updateShape({ ...node1, x, y });
126+
>node2 : { type: "node"; x: number; y: number; id: string; props: { nodeType: string; }; }
127+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^
128+
>editor.updateShape({ ...node1, x, y }) : { type: "node"; x: number; y: number; id: string; props: { nodeType: string; }; }
129+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^
130+
>editor.updateShape : <T extends TLShape = TLShape>(partial: TLShapePartial<T> | null | undefined) => T
131+
> : ^ ^^^^^^^^^ ^^^^^^^^^^^^ ^^ ^^^^^
132+
>editor : Editor
133+
> : ^^^^^^
134+
>updateShape : <T extends TLShape = TLShape>(partial: TLShapePartial<T> | null | undefined) => T
135+
> : ^ ^^^^^^^^^ ^^^^^^^^^^^^ ^^ ^^^^^
136+
>{ ...node1, x, y } : { x: number; y: number; type: "node"; id: string; props: { nodeType: string; }; }
137+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ ^^^^^^^^^ ^^^
138+
>node1 : NodeShape
139+
> : ^^^^^^^^^
140+
>x : number
141+
> : ^^^^^^
142+
>y : number
143+
> : ^^^^^^
144+
145+
declare const shape1: TLShape;
146+
>shape1 : TLShape
147+
> : ^^^^^^^
148+
149+
const shape2 = editor.updateShape({ ...shape1, x, y });
150+
>shape2 : TLShape
151+
> : ^^^^^^^
152+
>editor.updateShape({ ...shape1, x, y }) : TLShape
153+
> : ^^^^^^^
154+
>editor.updateShape : <T extends TLShape = TLShape>(partial: TLShapePartial<T> | null | undefined) => T
155+
> : ^ ^^^^^^^^^ ^^^^^^^^^^^^ ^^ ^^^^^
156+
>editor : Editor
157+
> : ^^^^^^
158+
>updateShape : <T extends TLShape = TLShape>(partial: TLShapePartial<T> | null | undefined) => T
159+
> : ^ ^^^^^^^^^ ^^^^^^^^^^^^ ^^ ^^^^^
160+
>{ ...shape1, x, y } : { x: number; y: number; type: "arrow"; id: string; props: { dir: 1 | -1; }; } | { x: number; y: number; type: "node"; id: string; props: { nodeType: string; }; }
161+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ ^^^^^^^^^ ^^^
162+
>shape1 : TLShape
163+
> : ^^^^^^^
164+
>x : number
165+
> : ^^^^^^
166+
>y : number
167+
> : ^^^^^^
168+

0 commit comments

Comments
 (0)