Skip to content

Explicitly annotated unique symbols are widened in return positions #55361

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

Open
Andarist opened this issue Aug 14, 2023 · 5 comments
Open

Explicitly annotated unique symbols are widened in return positions #55361

Andarist opened this issue Aug 14, 2023 · 5 comments
Labels
Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases
Milestone

Comments

@Andarist
Copy link
Contributor

Andarist commented Aug 14, 2023

πŸ”Ž Search Terms

widening return unique symbol

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.3.0-dev.20230814&ssl=6&ssc=2&pln=1&pc=1#code/KYDwDg9gTgLgBAYwgOwM7xsdcC8cDKAngLYBGEANgBQCUAUHaJLHAGYCuyCMAlim8lpwA3nTjjEKbAEMKPaagBccGITDAIrFVnh5M6ANxiJUYDHZRkcWfNR0AvkA

πŸ’» Code

export const test = Symbol()

export function fn() {
    const alias: typeof test = test;
    return alias
}

πŸ™ Actual behavior

this declaration file is emitted:

export declare const test: unique symbol;
export declare function fn(): symbol;

πŸ™‚ Expected behavior

this declaration file to be emitted:

export declare const test: unique symbol;
export declare function fn(): typeof test;

Additional information

getWidenedLiteralLikeTypeForContextualReturnTypeIfNeeded calls getWidenedLiteralLikeTypeForContextualType and that calls getWidenedUniqueESSymbolType when there is no contextual type provided.

some issues that are (partially~) related:
#32242
#35896 (comment)
#36876

@fatcerberus
Copy link

I think you may have just found the underlying cause of #53276 πŸ˜„

@Andarist
Copy link
Contributor Author

This issue is actually different and I'm already fixing it here: #54778 πŸ˜… Different code paths handle widening from initializers and widening at return positions.

@RyanCavanaugh RyanCavanaugh added the Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases label Aug 15, 2023
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Aug 15, 2023
@RyanCavanaugh
Copy link
Member

I'm not sure I'd call the existing behavior wrong, but it seems like a safe change to make

@ssalbdivad
Copy link

ssalbdivad commented Aug 15, 2023

@RyanCavanaugh Are there other situations where casting the only return statement of a function doesn't dictate how it's inferred?

Could even be simplified down to just:

export const test = Symbol()

// inferred as () => symbol
const fn = () => test as typeof test

@Andarist
Copy link
Contributor Author

I'm not sure I'd call the existing behavior wrong, but it seems like a safe change to make

Are there any other cases in the compiler where an explicit type annotation like this gets stomped by the compiler and the type gets widened? I'm really curious about this. I assume that there is no place like this and that's why I'm calling this a bug. I also understand that symbols are somewhat special but as long as the symbol is publicly available (so the declaration emit can actually reference it) I think the annotation should be preserved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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

4 participants