Skip to content

Instantly share code, notes, and snippets.

@Krever
Created July 4, 2020 18:37
Show Gist options
  • Save Krever/5d8e067a3eb19c4dad16eeae28bb5a9c to your computer and use it in GitHub Desktop.
Save Krever/5d8e067a3eb19c4dad16eeae28bb5a9c to your computer and use it in GitHub Desktop.
Newsubtypes in TS
type Tag = { readonly __tag: symbol }
export type NewSubtype<Base, Tagg extends Tag> = Base & Tagg;
export type NewSubtypeCompanion<T extends NewSubtype<E, Tagg>, E = any, Tagg extends Tag = any> = {
create: (_: E) => NewSubtype<T, Tagg>
}
export const createNewtypeCompanion: <T extends NewSubtype<E, Tagg>, E = any, Tagg extends Tag = any>() => NewSubtypeCompanion<T, E> =
<T extends NewSubtype<E, Tagg>, E, Tagg extends Tag>() => ({
create: (x: E) => x as NewSubtype<T, Tagg>
})
type A = NewSubtype<number, { readonly __tag: unique symbol }>
const A: NewSubtypeCompanion<A> = createNewtypeCompanion()
type B = NewSubtype<number, { readonly __tag: unique symbol }>
const B: NewSubtypeCompanion<B> = createNewtypeCompanion<B>()
const f1 = (_: A) => null
const f2 = (_: number) => null
const b: B = B.create(2)
f1(b) // doesnt compile
f2(b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment