Skip to content

Type parameters are renamed in declarations #55653

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dragomirtitian opened this issue Sep 6, 2023 · 2 comments Β· Fixed by #55820
Closed

Type parameters are renamed in declarations #55653

dragomirtitian opened this issue Sep 6, 2023 · 2 comments Β· Fixed by #55820
Assignees
Labels
Fix Available A PR has been opened for this issue Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases Suggestion An idea for TypeScript

Comments

@dragomirtitian
Copy link
Contributor

πŸ”Ž Search Terms

type parameters declaration rename

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.2.2#code/MYGwhgzhAECC0G9oF8CwAoAbmATtARtALzQA8sANAHwAUAHgFxwCUxV0dQA

πŸ’» Code

class A { }
var b = <A,>(x: A) => x

πŸ™ Actual behavior

Declaration file type for b is declare var b: <A_1>(x: A_1) => A_1;

πŸ™‚ Expected behavior

Declaration file type for b should be declare var b: <A>(x: A) => A; as written in source code. There is no reason to rename the type parameter

Additional information about the issue

No response

@jakebailey
Copy link
Member

My understanding (from skimming + the last time I touched this) is that the determination for "should I rename the type parameter" is just "does something exist in scope in type space with the same name", so interface A also does this. But, that doesn't explain why this doesn't apply to functions:

class A { }
var a = <A,>(x: A) => x
function a2<A,>(x: A) { return x }

interface B { }
var b = <B,>(x: B) => x
function b2<B,>(x: B) { return x }
declare class A {
}
declare var a: <A_1>(x: A_1) => A_1;
declare function a2<A>(x: A): A;
interface B {
}
declare var b: <B_1>(x: B_1) => B_1;
declare function b2<B>(x: B): B;

I will note that you still need to be able to write:

class A { }
var a = <A,>(x: A) => new A()
function a2<A,>(x: A) { return new A() }
declare class A {
}
declare var a: <A_1>(x: A_1) => A;
declare function a2<A>(x: A): globalThis.A;

Exporting them nets:

export declare class A {
}
export declare var a: <A_1>(x: A_1) => A;
export declare function a2<A>(x: A): import("./input").A;

@jakebailey
Copy link
Member

I looked into this, and the reason the function declaration and the variable differ is because declaration emit walks declaration nodes directly (fixing up the AST there), whereas on the variable, all it has is the type and so it hands it off directly to typeToTypeNode. The former is able to walk the declaration's type parameters first and decides to use them as-is (which then causes the return to have to be redone), whereas the latter goes through signatureToSignatureDeclarationHelper which sees the outer A and decides to rename (letting the return type remain as-is instead).

@andrewbranch andrewbranch added the Needs Investigation This issue needs a team member to investigate its status. label Sep 11, 2023
@jakebailey jakebailey added Suggestion An idea for TypeScript Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases Fix Available A PR has been opened for this issue and removed Needs Investigation This issue needs a team member to investigate its status. labels Sep 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fix Available A PR has been opened for this issue Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants