This:
type Foo = {
bar: string
// …
}
Can just as easily be addressed as: const parseFoo = parse.object({
bar: parse.string,
// …
})
type Foo = Foo<typeof parseFoo>
(Where parse methods here are type guards for their respective parsed return types, and can similarly be used to serialize runtime values as needed.)For that little bit of extra ceremony, you get to isolate runtime stuff to the boundaries you need to care about, and let the type checker deal with everything else (typically most everything internal).