Skip to content

Commit 28e4c81

Browse files
authored
Tweak co/contra inference logic from #52123 (#52180)
1 parent 14b0d6d commit 28e4c81

9 files changed

+1445
-2
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24590,8 +24590,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2459024590
// parameter and has inferences that would conflict. Otherwise, we use the contra-variant inference.
2459124591
const useCovariantType = inferredCovariantType && !(inferredCovariantType.flags & TypeFlags.Never) &&
2459224592
some(inference.contraCandidates, t => isTypeSubtypeOf(inferredCovariantType, t)) &&
24593-
every(context.inferences, other => other === inference ||
24594-
getConstraintOfTypeParameter(other.typeParameter) !== inference.typeParameter ||
24593+
every(context.inferences, other =>
24594+
other !== inference && getConstraintOfTypeParameter(other.typeParameter) !== inference.typeParameter ||
2459524595
every(other.candidates, t => isTypeSubtypeOf(t, inferredCovariantType)));
2459624596
inferredType = useCovariantType ? inferredCovariantType : getContravariantInference(inference);
2459724597
}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
//// [coAndContraVariantInferences3.ts]
2+
interface DeprecationOptions {
3+
message?: string;
4+
error?: boolean;
5+
name?: string;
6+
}
7+
8+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
9+
10+
type OverloadDefinitions = { readonly [P in number]: (...args: any[]) => any; };
11+
12+
type OverloadBinder<T extends OverloadDefinitions> = (args: OverloadParameters<T>) => OverloadKeys<T> | undefined;
13+
14+
type OverloadKeys<T extends OverloadDefinitions> = Extract<keyof T, number>;
15+
16+
type OverloadParameters<T extends OverloadDefinitions> = Parameters<{ [P in OverloadKeys<T>]: T[P]; }[OverloadKeys<T>]>;
17+
18+
type OverloadFunction<T extends OverloadDefinitions> = UnionToIntersection<T[keyof T]>;
19+
20+
type OverloadBinders<T extends OverloadDefinitions> = { [P in OverloadKeys<T>]: (args: OverloadParameters<T>) => boolean | undefined; };
21+
22+
type OverloadDeprecations<T extends OverloadDefinitions> = { [P in OverloadKeys<T>]?: DeprecationOptions; };
23+
24+
declare function createOverload<T extends OverloadDefinitions>(name: string, overloads: T, binder: OverloadBinders<T>, deprecations?: OverloadDeprecations<T>): UnionToIntersection<T[keyof T]>;
25+
26+
declare function createBinder<T extends OverloadDefinitions>(overloads: T, binder: OverloadBinders<T>): OverloadBinder<T>;
27+
28+
interface OverloadBuilder {
29+
overload<T extends OverloadDefinitions>(overloads: T): BindableOverloadBuilder<T>;
30+
}
31+
32+
interface BindableOverloadBuilder<T extends OverloadDefinitions> {
33+
bind(binder: OverloadBinders<T>): BoundOverloadBuilder<T>;
34+
}
35+
36+
interface FinishableOverloadBuilder<T extends OverloadDefinitions> {
37+
finish(): OverloadFunction<T>;
38+
}
39+
40+
interface BoundOverloadBuilder<T extends OverloadDefinitions> extends FinishableOverloadBuilder<T> {
41+
deprecate(deprecations: OverloadDeprecations<T>): FinishableOverloadBuilder<T>;
42+
}
43+
44+
declare function buildOverload(name: string): OverloadBuilder;
45+
46+
const enum SyntaxKind {
47+
ImportDeclaration,
48+
Modifier,
49+
ImportClause,
50+
AssertClause,
51+
Decorator
52+
}
53+
54+
interface Node {
55+
kind: SyntaxKind;
56+
}
57+
58+
interface Declaration extends Node { _declarationBrand: any }
59+
interface Statement extends Node { _statementBrand: any };
60+
interface Expression extends Node { _expressionBrand: any; }
61+
62+
interface ImportDeclaration extends Statement { kind: SyntaxKind.ImportDeclaration; }
63+
interface Modifier extends Node { kind: SyntaxKind.Modifier; }
64+
interface Decorator extends Node { kind: SyntaxKind.Decorator; }
65+
interface ImportClause extends Declaration { kind: SyntaxKind.ImportClause; }
66+
interface AssertClause extends Node { kind: SyntaxKind.AssertClause; }
67+
68+
declare function isExpression(node: Node): node is Expression;
69+
declare function isAssertClause(node: Node): node is AssertClause;
70+
declare function isImportClause(node: Node): node is ImportClause;
71+
declare function isModifier(node: Node): node is Modifier;
72+
declare function isDecorator(node: Node): node is Decorator;
73+
74+
declare const updateImportDeclaration: {
75+
(node: ImportDeclaration, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, assertClause: AssertClause | undefined): ImportDeclaration;
76+
(node: ImportDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, assertClause: AssertClause | undefined): ImportDeclaration;
77+
}
78+
79+
declare function every<T, U extends T>(array: readonly T[], callback: (element: T, index: number) => element is U): array is readonly U[];
80+
declare function every<T, U extends T>(array: readonly T[] | undefined, callback: (element: T, index: number) => element is U): array is readonly U[] | undefined;
81+
declare function every<T>(array: readonly T[] | undefined, callback: (element: T, index: number) => boolean): boolean;
82+
83+
declare function isArray(value: any): value is readonly unknown[];
84+
85+
declare const DISALLOW_DECORATORS: DeprecationOptions;
86+
87+
buildOverload("updateImportDeclaration")
88+
.overload({
89+
0(node: ImportDeclaration, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, assertClause: AssertClause | undefined): ImportDeclaration {
90+
return updateImportDeclaration(node, modifiers, importClause, moduleSpecifier, assertClause);
91+
},
92+
93+
1(node: ImportDeclaration, _decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, assertClause: AssertClause | undefined): ImportDeclaration {
94+
return updateImportDeclaration(node, modifiers, importClause, moduleSpecifier, assertClause);
95+
},
96+
})
97+
.bind({
98+
0: ([, modifiers, importClause, moduleSpecifier, assertClause, other]) =>
99+
(other === undefined) &&
100+
(modifiers === undefined || every(modifiers, isModifier)) &&
101+
(importClause === undefined || !isArray(importClause)) &&
102+
(moduleSpecifier === undefined || isExpression(moduleSpecifier)) &&
103+
(assertClause === undefined || isAssertClause(assertClause)),
104+
105+
1: ([, decorators, modifiers, importClause, moduleSpecifier, assertClause]) =>
106+
(decorators === undefined || every(decorators, isDecorator)) &&
107+
(modifiers === undefined || isArray(modifiers)) &&
108+
(importClause === undefined || isImportClause(importClause)) &&
109+
(moduleSpecifier !== undefined && isExpression(moduleSpecifier)) &&
110+
(assertClause === undefined || isAssertClause(assertClause)),
111+
})
112+
.deprecate({
113+
1: DISALLOW_DECORATORS
114+
})
115+
.finish();
116+
117+
118+
declare const modifiers: readonly Modifier[] | readonly Decorator[];
119+
120+
function foo() {
121+
every(modifiers, isModifier);
122+
every(modifiers, isDecorator);
123+
}
124+
125+
126+
//// [coAndContraVariantInferences3.js]
127+
"use strict";
128+
;
129+
buildOverload("updateImportDeclaration")
130+
.overload({
131+
0: function (node, modifiers, importClause, moduleSpecifier, assertClause) {
132+
return updateImportDeclaration(node, modifiers, importClause, moduleSpecifier, assertClause);
133+
},
134+
1: function (node, _decorators, modifiers, importClause, moduleSpecifier, assertClause) {
135+
return updateImportDeclaration(node, modifiers, importClause, moduleSpecifier, assertClause);
136+
},
137+
})
138+
.bind({
139+
0: function (_a) {
140+
var modifiers = _a[1], importClause = _a[2], moduleSpecifier = _a[3], assertClause = _a[4], other = _a[5];
141+
return (other === undefined) &&
142+
(modifiers === undefined || every(modifiers, isModifier)) &&
143+
(importClause === undefined || !isArray(importClause)) &&
144+
(moduleSpecifier === undefined || isExpression(moduleSpecifier)) &&
145+
(assertClause === undefined || isAssertClause(assertClause));
146+
},
147+
1: function (_a) {
148+
var decorators = _a[1], modifiers = _a[2], importClause = _a[3], moduleSpecifier = _a[4], assertClause = _a[5];
149+
return (decorators === undefined || every(decorators, isDecorator)) &&
150+
(modifiers === undefined || isArray(modifiers)) &&
151+
(importClause === undefined || isImportClause(importClause)) &&
152+
(moduleSpecifier !== undefined && isExpression(moduleSpecifier)) &&
153+
(assertClause === undefined || isAssertClause(assertClause));
154+
},
155+
})
156+
.deprecate({
157+
1: DISALLOW_DECORATORS
158+
})
159+
.finish();
160+
function foo() {
161+
every(modifiers, isModifier);
162+
every(modifiers, isDecorator);
163+
}

0 commit comments

Comments
 (0)