@kajetansw
kajetan.dev
Kajetan Świątek
👨🎨 Front-end developer
🇵🇱 Wrocław
(not every tool will meet all expectations of all users)
No interfaces
and type aliases
No runtime validation
interface Hero {
name: string;
gender: string;
}
const url = 'https://swapi.dev/api/people/1';
const hero: Hero =
await fetch(url).then(r => r.json());
// How sure are we that the returned object is
// really of type `Hero`?
elm
typescript-runtime-type-benchmarks
jquense/yup
⭐️ 16,787
ajv-validator/ajv
⭐️ 10,921
colinhacks/zod
⭐️ 7,118
gcanti/io-ts
⭐️ 5,366
pelotom/runtypes
⭐️ 2,074
import { z } from "zod";
// primitive values
z.string();
z.number();
z.bigint();
z.boolean();
z.date();
// empty types
z.undefined();
z.null();
// strings
z.string().max(5);
z.string().min(5);
z.string().length(5);
z.string().email();
z.string().url();
// etc.
// numbers
z.number().gt(5);
z.number().gte(5);
z.number().lt(5);
z.number().lte(5);
z.number().int();
// etc.
const Dog = z.object({
name: z.string(),
age: z.number(),
});
// extract the inferred type
type Dog = z.infer<typeof Dog>;
// equivalent to:
type Dog = {
name: string;
age: number;
};
Also combinators for
- extending
- merging
- picking
- omitting
// creating a schema for strings
const mySchema = z.string();
// parsing
mySchema.parse("tuna"); // "tuna"
mySchema.parse(12); // throws ZodError
// doesn't throw error if validation fails
mySchema.safeParse("tuna");
// { success: true; data: "tuna" }
mySchema.safeParse(12);
// { success: false; error: ZodError }
import * as t from 'io-ts'
// Primitives
t.string
t.number
// Combinators
const User = t.type({
userId: t.number,
name: t.string
})
type User = t.TypeOf<typeof User>
import * as t from 'io-ts'
// Decoding
t.string.decode(/*...*/)
// returns Either<E, A>
type Either<E, A> =
| {
readonly _tag: 'Left'
readonly left: E
}
| {
readonly _tag: 'Right'
readonly right: A
}
@kajetansw
kajetan.dev
typescript-runtime-type-benchmarks