unsplash / sum-types-io-ts

io-ts bindings for @unsplash/sum-types.
https://unsplash.github.io/sum-types-io-ts/
MIT License
2 stars 1 forks source link

Serialized type is inlined #1

Open samhh opened 2 years ago

samhh commented 2 years ago

https://github.com/unsplash/sum-types-io-ts/blob/33fa3b32acccdbb13534884e541df3147f1f3739/test/type/index.ts#L9

Small repro in sum-types repo (to prove it's not (only) because we're reconstructing it):

type Serialized1<A extends Sum.AnyMember> = [Tag<A>, Value<A>] // this preserves the name
type Serialized2<A> = A extends Sum.AnyMember ? [Tag<A>, Value<A>] : never // this does not

type X = Sum.Member<'X', string> | Sum.Member<'Y', number>

declare const x1: Serialized1<X> // aliased
if (x1[0] === "X") x1[1] // string | number
declare const x2: Serialized2<X> // expanded
if (x2[0] === "X") x2[1] // string

We're using the conditional type to distribute over union members.

As an aside we should probably export Serialized for both this and the fp-ts bindings repo. I also wonder if that would remove the need for some of the assertions?

samhh commented 1 year ago

This is a hack, but...:

type Serialized1<A extends Sum.AnyMember> = [Tag<A>, Value<A>]
type Serialized2<A> = A extends Sum.AnyMember ? [Tag<A>, Value<A>] : never
type Serialized3<A> = Serialized2<A> & {} // <- this intersection

type X = Sum.Member<'X', string> | Sum.Member<'Y', number>

declare const x1: Serialized1<X> // aliased
if (x1[0] === "X") x1[1] // string | number
declare const x2: Serialized2<X> // expanded
if (x2[0] === "X") x2[1] // string
declare const x3: Serialized3<X> // aliased
if (x3[0] === "X") x3[1] // string