Skip to content

Exported const type parameters is not renamed in constraint in another const in type declarations #56783

Description

🔎 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)

Metadata

Metadata

Labels

BugA bug in TypeScriptDomain: Declaration EmitThe issue relates to the emission of d.ts files

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions