Comments (9)
Adding a _tag
field to each *Type
(a trick used in fp-ts
) would allow for exhaustivity checks on custom defined unions
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'
}
}
from io-ts.
Is there any downside / upside to using any
for the type parameters? Instead of trying to preserve the type information?
from io-ts.
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']
from io-ts.
to build database schemas and stuff from the Type definition
@DylanRJohnston That's interesting, could you elaborate and/or show some practical example (in order to make sure the change above will be effective)?
from io-ts.
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 readonly _tag = StringLiteral
when there's a Type that inherits from another type, e.g.
class Foo {
readonly _tag = "Foo"
}
class Bar extends Foo {
readonly _tag = "Bar"
}
Class 'Bar' incorrectly extends base class 'Foo'.
Types of property '_tag' are incompatible.
Type '"Bar"' is not assignable to type '"Foo"'.
from io-ts.
It'd also be ideal to be able to case match on the different Type<primitive types>
types too. There's a cool library that uses class decorators to achieve the same thing. But we were hoping to stick with structural typing via interfaces instead of nominal typing via classes. Might have to bite the bullet and just use classes.
from io-ts.
I guess you could recover it by going
type ClassTags = "Foo" | "Bar"
interface HasTag {
readonly _tag : ClassTags
}
class Foo {
readonly _tag : ClassTags = "Foo"
}
class Bar extends Foo {
readonly _tag = "Bar"
}
function isFoo(x : HasTag): x is Foo {
return x._tag === "Foo";
}
function isBar(x : HasTag): x is Bar {
return x._tag === "Bar";
}
const assertNever = (x: never): never => {throw new Error(x);}
function foobar(x : Foo | Bar) {
if (isFoo(x)) {
return ""
} else if (isBar(x)) {
return ""
} else {
return assertNever(x);
}
}
from io-ts.
@DylanRJohnston You can find a proof of concept in the 50
branch
- But to leverage totality checking I need to be able to form some kind of tagged union of the Types in this package
- It'd also be ideal to be able to case match on the different Type types too
- a Type that inherits from another type (<= Q: does this still make sense? Now types are structural)
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? lib
is committed in so you can install it by running
npm i gcanti/io-ts#50
from io-ts.
Yes! Thank you so much. It works great.
from io-ts.
Related Issues (20)
- Behavior changes and types are incorrect based on `intersection` array order
- Intersection with record whose keys are a custom type HOT 1
- io-ts recursion use issue HOT 4
- Subpath imports in ESM mode HOT 5
- Clarification question - how to work with the type of codecs themselves? HOT 1
- Surprising acceptance of various inputs HOT 1
- ReadonlyNonEmptyArray can't be used in a mapped type HOT 1
- How to generate documentation for types generated with `t.TypeOf` HOT 1
- Difficulties with generic serialisable type HOT 2
- [Question] Typing a generic mapped union HOT 1
- Inference error for `toString` property in intersection types with TypeScript 4.9.5 HOT 1
- `t.TypeOf<keyof<o>>` should return a string union type, not a numeric union type.
- PSA: TS 5.1 can break using this library HOT 1
- Intersection of Function with Object doesn't validate correctly
- t.Int: use Number.isSafeInteger instead of Number.isInteger
- non-enumerable records with extra keys do not pass `io-ts.record.is`, contrary to TypeScript types HOT 12
- partially enumerable record missing enumerable keys passes `record.is`, contrary to TypeScript types
- Records are stripped when encoding with t.record(NumberFromString, xxx) HOT 2
- Question: Convert a form to a type with different structure
- Incorrect behaviour when used with browser geolocation coordinates object
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from io-ts.