Description
🔎 Search Terms
Generic methods
Constraints
Type parameters renaming
Type declarations
🕗 Version & Regression Information
- This changed between versions 4.3.5 and 4.4.4 (among versions present on playground)
- This changed in commit or PR f7a97b7 (Cache accessibe symbol chains and serialized type parameter name generation #43973, bisected with every-ts and manually inspecting .d.ts output)
⏯ Playground Link
💻 Code
type P2<L, R> = L & { [K in keyof R]: number };
type P<T> = { [K in keyof T]: number }
const Foo = {
f<I extends P2<{}, I>>() {},
g<I extends P<I>>() {},
};
const Bar = {
f<I extends P2<{}, I>>() {},
g<I extends P<I>>() {},
};
export const Baz = {
f<I extends P2<{}, I>>() {},
g<I extends P<I>>() {},
};
export const Def = {
foo: Foo,
bar: Bar,
baz: Baz,
};
🙁 Actual behavior
Generated .d.ts on v5.3.2 looks like this:
type P<T> = {
[K in keyof T]: number;
};
export declare const Baz: {
f<I extends { [K in keyof I]: number; }>(): void;
g<I_1 extends P<I_1>>(): void;
};
export declare const Def: {
foo: {
f<I extends { [K in keyof I]: number; }>(): void;
g<I_1 extends P<I_1>>(): void;
};
bar: {
f<I_2 extends { [K_1 in keyof I_2]: number; }>(): void;
g<I_3 extends P<I_3>>(): void;
};
baz: {
f<I_4 extends { [K in keyof I]: number; }>(): void;
g<I_5 extends P<I_5>>(): void;
};
};
export {};
Notice the line f<I_4 extends { [K in keyof I]: number; }>(): void;
in baz
, there's no I
in scope.
Same line in bar
, that's f<I_2 extends { [K_1 in keyof I_2]: number; }>(): void;
has type parameters correctly renamed, which points to export
ed consts specifically.
g<I_5 extends P<I_5>>(): void;
also have correct type params, so simple generic type like P
is not enough.
🙂 Expected behavior
Generated .d.ts on v4.3.5 looks like this:
declare type P<T> = {
[K in keyof T]: number;
};
export declare const Baz: {
f<I extends { [K in keyof I]: number; }>(): void;
g<I_1 extends P<I_1>>(): void;
};
export declare const Def: {
foo: {
f<I extends { [K in keyof I]: number; }>(): void;
g<I_1 extends P<I_1>>(): void;
};
bar: {
f<I_2 extends { [K_1 in keyof I_2]: number; }>(): void;
g<I_3 extends P<I_3>>(): void;
};
baz: {
f<I_4 extends { [K_2 in keyof I_4]: number; }>(): void;
g<I_5 extends P<I_5>>(): void;
};
};
export {};
Notice the line f<I_4 extends { [K_2 in keyof I_4]: number; }>(): void;
, all type parameters nave been correctly renamed.
Additional information about the issue
Bisected commit passes sniff test: it introduces type caching and accessibility tracking, so maybe some of that triggers when emitting first constant, and poisons cache for visitDeclarationSubtree -> ... -> signatureToSignatureDeclarationHelper -> ... -> typeParameterToDeclaration
call later
Origin of this issue is code generated by ts-proto with outputServices=generic-definitions
option. See gist for example. Problem occuring here, on lines 70-79 in a.d.ts, where create
and fromPartial
have renamed type parameter, but original constraint (seemingly, from export declare const FooResponse
)