Is there a way to create nominal types in TypeScript that extend primitive types?

You can approximate opaque / nominal types in Typescript using a helper type. See this answer for more details:

// Helper for generating Opaque types.
type Opaque<T, K> = T & { __opaque__: K };

// 2 opaque types created with the helper
type Int = Opaque<number, 'Int'>;
type ID = Opaque<number, 'ID'>;

// works
const x: Int = 1 as Int;
const y: ID = 5 as ID;
const z = x + y;

// doesn't work
const a: Int = 1;
const b: Int = x;

// also works so beware
const f: Int = 1.15 as Int;

Here’s a more detailed answer:
https://stackoverflow.com/a/50521248/20489

Also a good article on different ways to to do this:
https://michalzalecki.com/nominal-typing-in-typescript/

Leave a Comment