Skip to content

Cannot create a unique symbol at each function call #40106

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
5 tasks done
kube opened this issue Aug 18, 2020 · 4 comments
Closed
5 tasks done

Cannot create a unique symbol at each function call #40106

kube opened this issue Aug 18, 2020 · 4 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@kube
Copy link

kube commented Aug 18, 2020

Search Terms

Symbol, unique, generated, function call

Suggestion

With two functions returning unique symbol.

declare function randomSymbol(): { readonly id: unique symbol };
declare function randomSymbol2(): { readonly id: unique symbol };

When comparing the symbol types when calling these two functions, we get a (correct) error from the compiler telling us that these types are incompatible.

const a = randomSymbol();
const b = randomSymbol2();

a.id === a.id;
a.id === b.id; // TS ERROR: Expected behaviour. 👍 

If we call the same function two times though, the types are the same.

const a = randomSymbol();
const b = randomSymbol();

a.id === a.id;
a.id === b.id; // NO ERROR: But I would expect these two types to be different too 👎 

I understand that this can be expected in some cases, though there is currently no way to tell the compiler to generate a different unique symbol for each function call.

Use Cases

My current use-case is for creating two objects using the same constructor, that are structurally identical, but that would not be compatible between them (kind of opaque types).

Maybe this should be through the usage of a new keyword to prevent compatibility issues with existing codebases.

Examples

https://www.typescriptlang.org/play?#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXxilWBwFsBlAT1ICMcIAKASgC54BvAkKE1CS+FmBs0WAI7IEAZ2p0I8AL4BuAFChIsBCnTY8BIiQqz6AJmZtOcHnn6Dh8UROnH5ylSvYr48MHikZ4KHgAXn1iMipaemZVb19Uf3gaELDDSLkzJlUvQIA6IRDg0Kh84Fi8gqLQmlKleAB6evgAeQBpFQV3Tzi-AKDQwnCjKMYsnPjE5IGDCJcY928SyqKKspyl4ELq2oamgEl4AHccZAhNkAAPAAdwAIwACxApBAxj+AxKG6l3nCSEYCwiEQIDgqDuOBwHRUQA

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Aug 20, 2020
@RyanCavanaugh
Copy link
Member

There are two valid interpretations of what this means:

  • This function, every time it's called, returns the same symbol that isn't manifested anywhere else in the program
  • This function, every time it's called, returns a new symbol that isn't manifested anywhere else in the program, including previous calls

It's not really obvious how you would reason about the second one, since there's not any tracking of any sort of "This symbol came from this invocation" or a way to talk about that in a type syntax position.

@typescript-bot
Copy link
Collaborator

This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@ExE-Boss
Copy link
Contributor

@RyanCavanaugh
To disambiguate those cases, it might be a good idea to use new symbol for the second case: #37469

@jcalz
Copy link
Contributor

jcalz commented Feb 6, 2022

  • This function, every time it's called, returns a new symbol that isn't manifested anywhere else in the program, including previous calls. It's not really obvious how you would reason about [that], since there's not any tracking of any sort of "This symbol came from this invocation" or a way to talk about that in a type syntax position.

This already happens magically when you assign the value returned from Symbol to a new variable, which gets inferred as unique symbol, right? So the ask here (and part of #37469) is to express what Symbol() does in the type system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

6 participants
@jcalz @kube @ExE-Boss @RyanCavanaugh @typescript-bot and others