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

Suggestion: add generic tagged objects to core library #10882

Closed
SimonMeskens opened this issue Sep 12, 2016 · 1 comment
Closed

Suggestion: add generic tagged objects to core library #10882

SimonMeskens opened this issue Sep 12, 2016 · 1 comment
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript

Comments

@SimonMeskens
Copy link

A lot of suggestions have been around nominal typing. A fair share of those are made by people who are pleasantly surprised to discover the tagged interface method. I propose adding @RyanCavanaugh's elegant generic solution to the library (and the documentation!), to help users discover this great feature. It would also avoid every popular Typescript library eventually adding their own version of this. I know I was surprised to find it and I would have loved to discover it sooner.

type Branded<T, U> = T & { [Symbol.species]: U };

Example use:

// UUID or a symbol, once symbol literal types are supported
type OrderUUID = "d3a8e9b5-07c2-4a2d-a245-8a5908826b0f";

// Tagged Alias
type OrderID = Branded<string, OrderUUID>;

It may be useful to split this into a type and an interface, though this may make it less elegant (and thus overreaching for inclusion in the core library):

interface Specified<T> {
    [Symbol.species]: T;
}

type Branded<T, U> = T & Specified<U>;

It does allow for more advanced uses of this system, such as runtime type checking:

// Is there a more elegant way to get a string literal type?
const OrderUUID = "d3a8e9b5-07c2-4a2d-a245-8a5908826b0f" as "d3a8e9b5-07c2-4a2d-a245-8a5908826b0f";

// Tagged Class
class Order implements Specified<typeof OrderUUID> {
    [Symbol.species] = "d3a8e9b5-07c2-4a2d-a245-8a5908826b0f" as typeof OrderUUID;
}

function isOrder(arg: any): arg is Order {
    return OrderUUID in arg;
}

The naming might need some discussion.

@RyanCavanaugh RyanCavanaugh added Needs Investigation This issue needs a team member to investigate its status. and removed Needs Investigation This issue needs a team member to investigate its status. labels May 24, 2017
@RyanCavanaugh RyanCavanaugh added Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript and removed Needs Investigation This issue needs a team member to investigate its status. labels Sep 20, 2019
@RyanCavanaugh
Copy link
Member

We've kicked this idea around a bunch of times and have opted to look into built-in solutions instead of adding types to the lib.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants