🔎 Search Terms
Generic methods
Constraints
Type parameters renaming
Type declarations
🕗 Version & Regression Information
⏯ Playground Link
https://www.typescriptlang.org/play?target=7&allowSyntheticDefaultImports=false&ts=5.3.2#code/C4TwDgpgBACgTAHgDIBooCUB8UC8UlQBkUA3lANoDSUAlgHZQDWEIA9gGYYC6AXFHQFcAtgCMIAJygBfANwBYAFCLQkWAgAq2PGSq0GzNp3W9+wsZKmLFAY1Z0AzsCgAxVq1ylFUb1HYIAklAQAB7AEHQAJvawiCRSaP6YmAAUAJSk8V4+AOYBQaHhUWqJKelxKIqyVgq2Dk4AQgCGktpZ3n6BIWGR0fAI5VAlaRkVCj5QuZ0FPcVJw+WV8koKIWCs4k61jlBNAF4eJG2+eV2FvbHxg3NlmWM5J9NFMAHXI4vVq+ubdtsAIhCcVp3dpuPiuVijcYiZp8JriSE+aG7WGNXajKrLIA
💻 Code
typeP2<L,R>=L&{[KinkeyofR]: number};typeP<T>={[KinkeyofT]: number}constFoo={f<IextendsP2<{},I>>(){},g<IextendsP<I>>(){},};constBar={f<IextendsP2<{},I>>(){},g<IextendsP<I>>(){},};exportconstBaz={f<IextendsP2<{},I>>(){},g<IextendsP<I>>(){},};exportconstDef={foo: Foo,bar: Bar,baz: Baz,};🙁 Actual behavior
Generated .d.ts on v5.3.2 looks like this:
typeP<T>={[KinkeyofT]: number;};exportdeclareconstBaz: {f<Iextends{[KinkeyofI]: number;}>(): void;g<I_1extendsP<I_1>>(): void;};exportdeclareconstDef: {foo: {f<Iextends{[KinkeyofI]: number;}>(): void;g<I_1extendsP<I_1>>(): void;};bar: {f<I_2extends{[K_1inkeyofI_2]: number;}>(): void;g<I_3extendsP<I_3>>(): void;};baz: {f<I_4extends{[KinkeyofI]: number;}>(): void;g<I_5extendsP<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 exported 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:
declaretypeP<T>={[KinkeyofT]: number;};exportdeclareconstBaz: {f<Iextends{[KinkeyofI]: number;}>(): void;g<I_1extendsP<I_1>>(): void;};exportdeclareconstDef: {foo: {f<Iextends{[KinkeyofI]: number;}>(): void;g<I_1extendsP<I_1>>(): void;};bar: {f<I_2extends{[K_1inkeyofI_2]: number;}>(): void;g<I_3extendsP<I_3>>(): void;};baz: {f<I_4extends{[K_2inkeyofI_4]: number;}>(): void;g<I_5extendsP<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)
🔎 Search Terms
Generic methods
Constraints
Type parameters renaming
Type declarations
🕗 Version & Regression Information
⏯ Playground Link
https://www.typescriptlang.org/play?target=7&allowSyntheticDefaultImports=false&ts=5.3.2#code/C4TwDgpgBACgTAHgDIBooCUB8UC8UlQBkUA3lANoDSUAlgHZQDWEIA9gGYYC6AXFHQFcAtgCMIAJygBfANwBYAFCLQkWAgAq2PGSq0GzNp3W9+wsZKmLFAY1Z0AzsCgAxVq1ylFUb1HYIAklAQAB7AEHQAJvawiCRSaP6YmAAUAJSk8V4+AOYBQaHhUWqJKelxKIqyVgq2Dk4AQgCGktpZ3n6BIWGR0fAI5VAlaRkVCj5QuZ0FPcVJw+WV8koKIWCs4k61jlBNAF4eJG2+eV2FvbHxg3NlmWM5J9NFMAHXI4vVq+ubdtsAIhCcVp3dpuPiuVijcYiZp8JriSE+aG7WGNXajKrLIA
💻 Code
🙁 Actual behavior
Generated .d.ts on v5.3.2 looks like this:
Notice the line
f<I_4 extends { [K in keyof I]: number; }>(): void;inbaz, there's noIin scope.Same line in
bar, that'sf<I_2 extends { [K_1 in keyof I_2]: number; }>(): void;has type parameters correctly renamed, which points toexported consts specifically.g<I_5 extends P<I_5>>(): void;also have correct type params, so simple generic type likePis not enough.🙂 Expected behavior
Generated .d.ts on v4.3.5 looks like this:
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 -> ... -> typeParameterToDeclarationcall laterOrigin of this issue is code generated by ts-proto with
outputServices=generic-definitionsoption. See gist for example. Problem occuring here, on lines 70-79 in a.d.ts, wherecreateandfromPartialhave renamed type parameter, but original constraint (seemingly, fromexport declare const FooResponse)