Skip to content

Commit 50d70a3

Browse files
authored
Ensure stable ordering in getInferTypeParameters result (#64621)
1 parent f9f8d01 commit 50d70a3

5 files changed

Lines changed: 263 additions & 0 deletions

File tree

‎tsc/internal/checker/checker.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24300,6 +24300,7 @@ func (c *Checker) getInferTypeParameters(node *ast.Node) []*Type {
2430024300
result = append(result, c.getDeclaredTypeOfSymbol(symbol))
2430124301
}
2430224302
}
24303+
slices.SortFunc(result, CompareTypes)
2430324304
return result
2430424305
}
2430524306

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//// [tests/cases/compiler/stableTypeMapperOrdering.ts] ////
2+
3+
//// [stableTypeMapperOrdering.ts]
4+
// https://github.com/microsoft/TypeScript/issues/64589
5+
6+
interface Endpoint<Name, Params, Middleware, Services> {
7+
readonly name: Name;
8+
readonly params: Params;
9+
readonly middleware: Middleware;
10+
readonly services: Services;
11+
}
12+
13+
type Same<A, R> = R;
14+
15+
type AddMiddleware<E, I> =
16+
E extends Endpoint<infer N, infer P, infer M, infer S>
17+
? Endpoint<N, P, M | I, Same<I, S>>
18+
: never;
19+
20+
interface Group<Endpoints> {
21+
add<N extends string, P = never>(
22+
name: N,
23+
params?: P,
24+
): Group<Endpoints | Endpoint<N, P, never, never>>;
25+
middleware<I>(id: I): Group<AddMiddleware<Endpoints, I>>;
26+
}
27+
28+
declare const group: Group<never>;
29+
30+
export const result = group.add("a", { id: "" }).add("c").middleware("m" as const);
31+
32+
33+
//// [stableTypeMapperOrdering.js]
34+
// https://github.com/microsoft/TypeScript/issues/64589
35+
export const result = group.add("a", { id: "" }).add("c").middleware("m");
36+
37+
38+
//// [stableTypeMapperOrdering.d.ts]
39+
interface Endpoint<Name, Params, Middleware, Services> {
40+
readonly name: Name;
41+
readonly params: Params;
42+
readonly middleware: Middleware;
43+
readonly services: Services;
44+
}
45+
type Same<A, R> = R;
46+
type AddMiddleware<E, I> = E extends Endpoint<infer N, infer P, infer M, infer S> ? Endpoint<N, P, M | I, Same<I, S>> : never;
47+
interface Group<Endpoints> {
48+
add<N extends string, P = never>(name: N, params?: P): Group<Endpoints | Endpoint<N, P, never, never>>;
49+
middleware<I>(id: I): Group<AddMiddleware<Endpoints, I>>;
50+
}
51+
export declare const result: Group<Endpoint<"a", {
52+
id: string;
53+
}, "m", never> | Endpoint<"c", never, "m", never>>;
54+
export {};
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
//// [tests/cases/compiler/stableTypeMapperOrdering.ts] ////
2+
3+
=== stableTypeMapperOrdering.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/64589
5+
6+
interface Endpoint<Name, Params, Middleware, Services> {
7+
>Endpoint : Symbol(Endpoint, Decl(stableTypeMapperOrdering.ts, 0, 0))
8+
>Name : Symbol(Name, Decl(stableTypeMapperOrdering.ts, 2, 19))
9+
>Params : Symbol(Params, Decl(stableTypeMapperOrdering.ts, 2, 24))
10+
>Middleware : Symbol(Middleware, Decl(stableTypeMapperOrdering.ts, 2, 32))
11+
>Services : Symbol(Services, Decl(stableTypeMapperOrdering.ts, 2, 44))
12+
13+
readonly name: Name;
14+
>name : Symbol(Endpoint.name, Decl(stableTypeMapperOrdering.ts, 2, 56))
15+
>Name : Symbol(Name, Decl(stableTypeMapperOrdering.ts, 2, 19))
16+
17+
readonly params: Params;
18+
>params : Symbol(Endpoint.params, Decl(stableTypeMapperOrdering.ts, 3, 22))
19+
>Params : Symbol(Params, Decl(stableTypeMapperOrdering.ts, 2, 24))
20+
21+
readonly middleware: Middleware;
22+
>middleware : Symbol(Endpoint.middleware, Decl(stableTypeMapperOrdering.ts, 4, 26))
23+
>Middleware : Symbol(Middleware, Decl(stableTypeMapperOrdering.ts, 2, 32))
24+
25+
readonly services: Services;
26+
>services : Symbol(Endpoint.services, Decl(stableTypeMapperOrdering.ts, 5, 34))
27+
>Services : Symbol(Services, Decl(stableTypeMapperOrdering.ts, 2, 44))
28+
}
29+
30+
type Same<A, R> = R;
31+
>Same : Symbol(Same, Decl(stableTypeMapperOrdering.ts, 7, 1))
32+
>A : Symbol(A, Decl(stableTypeMapperOrdering.ts, 9, 10))
33+
>R : Symbol(R, Decl(stableTypeMapperOrdering.ts, 9, 12))
34+
>R : Symbol(R, Decl(stableTypeMapperOrdering.ts, 9, 12))
35+
36+
type AddMiddleware<E, I> =
37+
>AddMiddleware : Symbol(AddMiddleware, Decl(stableTypeMapperOrdering.ts, 9, 20))
38+
>E : Symbol(E, Decl(stableTypeMapperOrdering.ts, 11, 19))
39+
>I : Symbol(I, Decl(stableTypeMapperOrdering.ts, 11, 21))
40+
41+
E extends Endpoint<infer N, infer P, infer M, infer S>
42+
>E : Symbol(E, Decl(stableTypeMapperOrdering.ts, 11, 19))
43+
>Endpoint : Symbol(Endpoint, Decl(stableTypeMapperOrdering.ts, 0, 0))
44+
>N : Symbol(N, Decl(stableTypeMapperOrdering.ts, 12, 26))
45+
>P : Symbol(P, Decl(stableTypeMapperOrdering.ts, 12, 35))
46+
>M : Symbol(M, Decl(stableTypeMapperOrdering.ts, 12, 44))
47+
>S : Symbol(S, Decl(stableTypeMapperOrdering.ts, 12, 53))
48+
49+
? Endpoint<N, P, M | I, Same<I, S>>
50+
>Endpoint : Symbol(Endpoint, Decl(stableTypeMapperOrdering.ts, 0, 0))
51+
>N : Symbol(N, Decl(stableTypeMapperOrdering.ts, 12, 26))
52+
>P : Symbol(P, Decl(stableTypeMapperOrdering.ts, 12, 35))
53+
>M : Symbol(M, Decl(stableTypeMapperOrdering.ts, 12, 44))
54+
>I : Symbol(I, Decl(stableTypeMapperOrdering.ts, 11, 21))
55+
>Same : Symbol(Same, Decl(stableTypeMapperOrdering.ts, 7, 1))
56+
>I : Symbol(I, Decl(stableTypeMapperOrdering.ts, 11, 21))
57+
>S : Symbol(S, Decl(stableTypeMapperOrdering.ts, 12, 53))
58+
59+
: never;
60+
61+
interface Group<Endpoints> {
62+
>Group : Symbol(Group, Decl(stableTypeMapperOrdering.ts, 14, 12))
63+
>Endpoints : Symbol(Endpoints, Decl(stableTypeMapperOrdering.ts, 16, 16))
64+
65+
add<N extends string, P = never>(
66+
>add : Symbol(Group.add, Decl(stableTypeMapperOrdering.ts, 16, 28))
67+
>N : Symbol(N, Decl(stableTypeMapperOrdering.ts, 17, 6))
68+
>P : Symbol(P, Decl(stableTypeMapperOrdering.ts, 17, 23))
69+
70+
name: N,
71+
>name : Symbol(name, Decl(stableTypeMapperOrdering.ts, 17, 35))
72+
>N : Symbol(N, Decl(stableTypeMapperOrdering.ts, 17, 6))
73+
74+
params?: P,
75+
>params : Symbol(params, Decl(stableTypeMapperOrdering.ts, 18, 12))
76+
>P : Symbol(P, Decl(stableTypeMapperOrdering.ts, 17, 23))
77+
78+
): Group<Endpoints | Endpoint<N, P, never, never>>;
79+
>Group : Symbol(Group, Decl(stableTypeMapperOrdering.ts, 14, 12))
80+
>Endpoints : Symbol(Endpoints, Decl(stableTypeMapperOrdering.ts, 16, 16))
81+
>Endpoint : Symbol(Endpoint, Decl(stableTypeMapperOrdering.ts, 0, 0))
82+
>N : Symbol(N, Decl(stableTypeMapperOrdering.ts, 17, 6))
83+
>P : Symbol(P, Decl(stableTypeMapperOrdering.ts, 17, 23))
84+
85+
middleware<I>(id: I): Group<AddMiddleware<Endpoints, I>>;
86+
>middleware : Symbol(Group.middleware, Decl(stableTypeMapperOrdering.ts, 20, 53))
87+
>I : Symbol(I, Decl(stableTypeMapperOrdering.ts, 21, 13))
88+
>id : Symbol(id, Decl(stableTypeMapperOrdering.ts, 21, 16))
89+
>I : Symbol(I, Decl(stableTypeMapperOrdering.ts, 21, 13))
90+
>Group : Symbol(Group, Decl(stableTypeMapperOrdering.ts, 14, 12))
91+
>AddMiddleware : Symbol(AddMiddleware, Decl(stableTypeMapperOrdering.ts, 9, 20))
92+
>Endpoints : Symbol(Endpoints, Decl(stableTypeMapperOrdering.ts, 16, 16))
93+
>I : Symbol(I, Decl(stableTypeMapperOrdering.ts, 21, 13))
94+
}
95+
96+
declare const group: Group<never>;
97+
>group : Symbol(group, Decl(stableTypeMapperOrdering.ts, 24, 13))
98+
>Group : Symbol(Group, Decl(stableTypeMapperOrdering.ts, 14, 12))
99+
100+
export const result = group.add("a", { id: "" }).add("c").middleware("m" as const);
101+
>result : Symbol(result, Decl(stableTypeMapperOrdering.ts, 26, 12))
102+
>group.add("a", { id: "" }).add("c").middleware : Symbol(Group.middleware, Decl(stableTypeMapperOrdering.ts, 20, 53))
103+
>group.add("a", { id: "" }).add : Symbol(Group.add, Decl(stableTypeMapperOrdering.ts, 16, 28))
104+
>group.add : Symbol(Group.add, Decl(stableTypeMapperOrdering.ts, 16, 28))
105+
>group : Symbol(group, Decl(stableTypeMapperOrdering.ts, 24, 13))
106+
>add : Symbol(Group.add, Decl(stableTypeMapperOrdering.ts, 16, 28))
107+
>id : Symbol(id, Decl(stableTypeMapperOrdering.ts, 26, 38))
108+
>add : Symbol(Group.add, Decl(stableTypeMapperOrdering.ts, 16, 28))
109+
>middleware : Symbol(Group.middleware, Decl(stableTypeMapperOrdering.ts, 20, 53))
110+
>const : Symbol(const)
111+
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//// [tests/cases/compiler/stableTypeMapperOrdering.ts] ////
2+
3+
=== stableTypeMapperOrdering.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/64589
5+
6+
interface Endpoint<Name, Params, Middleware, Services> {
7+
readonly name: Name;
8+
>name : Name
9+
10+
readonly params: Params;
11+
>params : Params
12+
13+
readonly middleware: Middleware;
14+
>middleware : Middleware
15+
16+
readonly services: Services;
17+
>services : Services
18+
}
19+
20+
type Same<A, R> = R;
21+
>Same : R
22+
23+
type AddMiddleware<E, I> =
24+
>AddMiddleware : AddMiddleware<E, I>
25+
26+
E extends Endpoint<infer N, infer P, infer M, infer S>
27+
? Endpoint<N, P, M | I, Same<I, S>>
28+
: never;
29+
30+
interface Group<Endpoints> {
31+
add<N extends string, P = never>(
32+
>add : <N extends string, P = never>(name: N, params?: P) => Group<Endpoints | Endpoint<N, P, never, never>>
33+
34+
name: N,
35+
>name : N
36+
37+
params?: P,
38+
>params : P | undefined
39+
40+
): Group<Endpoints | Endpoint<N, P, never, never>>;
41+
middleware<I>(id: I): Group<AddMiddleware<Endpoints, I>>;
42+
>middleware : <I>(id: I) => Group<AddMiddleware<Endpoints, I>>
43+
>id : I
44+
}
45+
46+
declare const group: Group<never>;
47+
>group : Group<never>
48+
49+
export const result = group.add("a", { id: "" }).add("c").middleware("m" as const);
50+
>result : Group<Endpoint<"a", { id: string; }, "m", never> | Endpoint<"c", never, "m", never>>
51+
>group.add("a", { id: "" }).add("c").middleware("m" as const) : Group<Endpoint<"a", { id: string; }, "m", never> | Endpoint<"c", never, "m", never>>
52+
>group.add("a", { id: "" }).add("c").middleware : <I>(id: I) => Group<Endpoint<"a", { id: string; }, I, never> | Endpoint<"c", never, I, never>>
53+
>group.add("a", { id: "" }).add("c") : Group<Endpoint<"a", { id: string; }, never, never> | Endpoint<"c", never, never, never>>
54+
>group.add("a", { id: "" }).add : <N extends string, P = never>(name: N, params?: P | undefined) => Group<Endpoint<"a", { id: string; }, never, never> | Endpoint<N, P, never, never>>
55+
>group.add("a", { id: "" }) : Group<Endpoint<"a", { id: string; }, never, never>>
56+
>group.add : <N extends string, P = never>(name: N, params?: P | undefined) => Group<Endpoint<N, P, never, never>>
57+
>group : Group<never>
58+
>add : <N extends string, P = never>(name: N, params?: P | undefined) => Group<Endpoint<N, P, never, never>>
59+
>"a" : "a"
60+
>{ id: "" } : { id: string; }
61+
>id : string
62+
>"" : ""
63+
>add : <N extends string, P = never>(name: N, params?: P | undefined) => Group<Endpoint<"a", { id: string; }, never, never> | Endpoint<N, P, never, never>>
64+
>"c" : "c"
65+
>middleware : <I>(id: I) => Group<Endpoint<"a", { id: string; }, I, never> | Endpoint<"c", never, I, never>>
66+
>"m" as const : "m"
67+
>"m" : "m"
68+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// @declaration: true
2+
3+
// https://github.com/microsoft/TypeScript/issues/64589
4+
5+
interface Endpoint<Name, Params, Middleware, Services> {
6+
readonly name: Name;
7+
readonly params: Params;
8+
readonly middleware: Middleware;
9+
readonly services: Services;
10+
}
11+
12+
type Same<A, R> = R;
13+
14+
type AddMiddleware<E, I> =
15+
E extends Endpoint<infer N, infer P, infer M, infer S>
16+
? Endpoint<N, P, M | I, Same<I, S>>
17+
: never;
18+
19+
interface Group<Endpoints> {
20+
add<N extends string, P = never>(
21+
name: N,
22+
params?: P,
23+
): Group<Endpoints | Endpoint<N, P, never, never>>;
24+
middleware<I>(id: I): Group<AddMiddleware<Endpoints, I>>;
25+
}
26+
27+
declare const group: Group<never>;
28+
29+
export const result = group.add("a", { id: "" }).add("c").middleware("m" as const);

0 commit comments

Comments
 (0)