typescript-book icon indicating copy to clipboard operation
typescript-book copied to clipboard

Another patch for Nominal Type

Open andresmoschini opened this issue 5 years ago • 3 comments

In this article, as a introduction to another thing, the author shows another kind of patch to use nominal types:

interface PersonIdBrand { _type: "Person"; }
type PersonId = PersonIdBrand & number;

interface BlogPostIdBrand { _type: "BlogPost"; }
type BlogPostId = number & BlogPostIdBrand;

It worked better for me with type inference than your approach with enums.

Do you think that is a good idea to add this alternative? or is there a well known issue with this approach?

andresmoschini avatar Mar 12 '20 00:03 andresmoschini

The type inference works better for me in this scenario:

type A = string & { _type: 'A' };
type B = string & { _type: 'B' };
type C = string & { _type: 'C' };
type D = A | B | C;

const f = (a: A, b: B, c: C) => a || b || c; 
// Infers: const f: (a: A, b: B, c: C) => D ✅
enum ABrand {  _ = '' }
type A = string & ABrand;
enum BBrand {  _ = '' }
type B = string & BBrand;
enum CBrand {  _ = '' }
type C = string & CBrand;
type D = A | B | C;

const f = (a: A, b: B, c: C) => a || b || c; 
// Infers: const f: (a: A, b: B, c: C) => C 💔

andresmoschini avatar Mar 12 '20 00:03 andresmoschini

An alternative, more similar to your Interface related one is:

type A = string & { _aBrand: any; }
type B = string & { _bBrand: any; }
type C = string & { _cBrand: any; }
type D = A | B | C;

const f = (a: A, b: B, c: C) => a || b || c;
// Infers: const f: (a: A, b: B, c: C) => D ✅

andresmoschini avatar Mar 12 '20 01:03 andresmoschini

:+1: Needs to be added as Using intersection types at some point :rose:

basarat avatar Mar 18 '20 22:03 basarat