@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