Skip to content
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

Isolated declarations quick fix defaults to including renamed properties #59547

Open
MichaelMitchell-at opened this issue Aug 7, 2024 · 1 comment
Labels
Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases
Milestone

Comments

@MichaelMitchell-at
Copy link

MichaelMitchell-at commented Aug 7, 2024

πŸ”Ž Search Terms

isolated declarations quick fix rename ts2842 ts9007

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

https://www.typescriptlang.org/play/?isolatedDeclarations=true&ts=5.6.0-dev.20240807#code/KYDwDg9gTgLgBAMwK4DsDGMCWEWIBQCUcA3gFBwVxTAxJS5x57ECGAXHAEYC HrHABm4EOANwiYAJnAC8APhLCAhAG5S3IA

πŸ’» Code

export function f() {
    return  (({a: b}: {a: 0}): void => {})!;
}

πŸ™ Actual behavior

Quick fix introduces a type error:

export function f(): ({ a: b }: { a: 0; }) => void {
//                         ~
//                         'b' is an unused renaming of 'a'. Did you intend to use it as a type annotation? (2842)
    return  (({a: b}: {a: 0}): void => {})!;
}

πŸ™‚ Expected behavior

export function f(): ({a}: { a: 0; }) => void {
    return  (({a: b}: {a: 0}): void => {})!;
}

Additional information about the issue

While the quick fix is consistent with the emitted declaration, it ideally wouldn't lead to another type error which can be avoided.
There are cases where it may make sense to preserve the renaming, most obviously

export function f(): ({ a: b }: { a: 0; }) => typeof b {
    return (({a: b}: {a: 0}): typeof b => b)!;
}

but also perhaps

export function f() {
    return  (({a: b}: {a: 0}, a: {}): void => {})!;
}

though, maybe surprisingly, this would currently this still result in ts(2842)

export function f(): ({ a: b }: { a: 0; }, a: {}) => void {
//                         ~
//                         'b' is an unused renaming of 'a'. Did you intend to use it as a type annotation? (2842)
    return  (({a: b}: {a: 0}, a: {}): void => {})!;
}

Perhaps this could be relaxed. While b is unused in the direct sense, it technically has value in that it avoids the naming collision between the as.

@jakebailey
Copy link
Member

jakebailey commented Aug 7, 2024

IIRC we've tried to fix this particular thing multiple times now (at least for declaration emit), and have ended up just reverting all of the code that tries to elide these as the effort was just far too error-fraught.

See also:

Maybe we can do better in the quick fix? But, then the quick fix would produce a result that differs from declaration emit via inference. It just seems like exactly the same problem space.

@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases labels Aug 8, 2024
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Aug 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases
Projects
None yet
Development

No branches or pull requests

3 participants