Support a union Shape or polymorphic types
sam-goodwin opened this issue · comments
It should be possible to define union types for things such as polymorphic DynamoDB Tables.
See: #103 for customer request.
Ex. usage:
union([string, integer, A, array(string)])
Should also support tagged unions. I wonder if we could introduce literal types for this use case:
class A extends Record({
tag: 'A'
}) {}
class B extends Record({
tag: 'B'
}) {}
const taggedUnion = union([A, B], 'tag');
Useful mechanic for extracting a type from a tagged-union by its tag.
https://gcanti.github.io/typelevel-ts/modules/index.ts.html#taggedunionmember-type-alias
(Copied from above link)
Signature
export type TaggedUnionMember<A extends object, Tag extends keyof A, Value extends A[Tag]> = Extract<
A,
Record<Tag, Value>
>
Example
import { TaggedUnionMember } from 'typelevel-ts'
type A = { tag: 'A'; a: string }
type B = { tag: 'B'; b: number }
type C = A | B
export type Result = TaggedUnionMember<C, 'tag', 'A'> // A
As per #108:
I just realized that the pattern: class X extends <function call>
is the "Shape equivalent" of TS's type X = <type computation>
. This will come in handy for expressing all sorts of type computations, like unions:
// in the TypeScript type-system
type A = string | number;
// in the Shape type-system
class A extends Union([string, number]) {}
Pretty meta to now also have a mapped type equivalent in the data-based Shape type-system .. woah. "Shape" is turning out to be an incredibly expressive and powerful DDL.