-
Notifications
You must be signed in to change notification settings - Fork 330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tagged Union of Types #50
Comments
Adding a export class InterfaceType<P extends Props> extends Type<InterfaceOf<P>> {
+ readonly _tag: 'InterfaceType' = 'InterfaceType'
}
export class UnionType<RTS extends Array<Any>, U> extends Type<U> {
+ readonly _tag: 'UnionType' = 'UnionType'
} type T = t.InterfaceType<any> | t.UnionType<any, any>
function f(type: T): string {
switch (type._tag) {
case 'InterfaceType':
return 'interface'
case 'UnionType':
return 'union'
}
} |
Is there any downside / upside to using |
I don't think there's any downside. If needed, types can also be extracted const Person = t.interface({
name: t.string
})
// type A = { name: t.Type<string>; }
type A = typeof Person.props
const U = t.union([t.string, Person])
// type B = [t.Type<string>, t.InterfaceType<{ name: t.Type<string>; }>]
type B = typeof U.types
// type C = t.Type<string>
type C = typeof U.types[1]['props']['name'] |
@DylanRJohnston That's interesting, could you elaborate and/or show some practical example (in order to make sure the change above will be effective)? |
I was thinking of something in the vein of the generic deriving from Haskell, so you could define a function that is able to compute a value from any Type representation. I'm trying to get it to generate a Sequelize schema object. I think there's a problem with using the
|
It'd also be ideal to be able to case match on the different |
I guess you could recover it by going
|
@DylanRJohnston You can find a proof of concept in the
Example import * as t from 'io-ts'
type Primitive = t.StringType | t.NumberType
type Primitives = { [key: string]: Primitive }
interface Schemas extends Array<Schema> {}
type Union = t.UnionType<Schemas, any>
type Schema = t.InterfaceType<Primitives> | Union
declare function f(type: Schema): string
const A = t.interface({
a: t.string
})
const B = t.interface({
b: t.number
})
const C = t.interface({
c: t.boolean
})
const D = t.union([A, B])
const E = t.union([A, C])
f(A)
f(B)
f(C) // error: Type '"BooleanType"' is not assignable to type '"NumberType"'.
f(D)
f(E) // error Could you please try it out with your use case?
|
Yes! Thank you so much. It works great. |
I really love this library and was hoping to be able to write something similar to Haskell's generic functions. But to leverage totality checking I need to be able to form some kind of tagged union of the Types in this package. But I'm having some trouble.
I basically want something like this, where I can pass a Type object and a map of folds to handle each type of Type to build database schemas and stuff from the Type definition.
Any help would be greatly appreciated.
The text was updated successfully, but these errors were encountered: