Expressions
Array
const const arrays: Type<{
key: string[];
}>
arrays = const type: TypeParser
<{
readonly key: "string[]";
}, Type<{
key: string[];
}, {}>>(def: validateObjectLiteral<{
readonly key: "string[]";
}, {}, bindThis<{
readonly key: "string[]";
}>>) => Type<...> (+2 overloads)
type({
key: "string[]"
})
const const arrays: Type<{
key: string[];
}>
arrays = const type: TypeParser
<{
readonly key: Type<string[], {}>;
}, Type<{
key: string[];
}, {}>>(def: validateObjectLiteral<{
readonly key: Type<string[], {}>;
}, {}, bindThis<{
readonly key: Type<string[], {}>;
}>>) => Type<...> (+2 overloads)
type({
key: type.string.array()
})
const const arrays: Type<{
key: {
name: string;
}[];
}>
arrays = const type: TypeParser
<{
readonly key: readonly [{
readonly name: "string";
}, "[]"];
}, Type<{
key: {
name: string;
}[];
}, {}>>(def: validateObjectLiteral<{
readonly key: readonly [{
readonly name: "string";
}, "[]"];
}, {}, bindThis<{
readonly key: readonly [{
readonly name: "string";
}, "[]"];
}>>) => Type<...> (+2 overloads)
type({
key: [{ name: "string" }, "[]"]
})
const const arrays: Type<{
key: {
name: string;
}[];
}>
arrays = const type: TypeParser
<{
readonly key: Type<{
name: string;
}[], {}>;
}, Type<{
key: {
name: string;
}[];
}, {}>>(def: validateObjectLiteral<{
readonly key: Type<{
name: string;
}[], {}>;
}, {}, bindThis<{
readonly key: Type<{
name: string;
}[], {}>;
}>>) => Type<...> (+2 overloads)
type({
key: const type: TypeParser
<{
readonly name: "string";
}, "[]", readonly [], Type<{
name: string;
}[], {}>>(_0: validateObjectLiteral<{
readonly name: "string";
}, {}, bindThis<{
readonly name: "string";
}>>, _1: "[]") => Type<...> (+2 overloads)
type({ name: "string" }, "[]")
})
Divisibility
Constrain a number
to a multiple of the specified integer.
const const evens: Type<{
key: number.divisibleBy<2>;
}>
evens = const type: TypeParser
<{
readonly key: "number%2";
}, Type<{
key: number.divisibleBy<2>;
}, {}>>(def: validateObjectLiteral<{
readonly key: "number%2";
}, {}, bindThis<{
readonly key: "number%2";
}>>) => Type<...> (+2 overloads)
type({
key: "number%2"
})
const const evens: Type<{
key: number.divisibleBy<2>;
}>
evens = const type: TypeParser
<{
readonly key: Type<number.divisibleBy<2>, {}>;
}, Type<{
key: number.divisibleBy<2>;
}, {}>>(def: validateObjectLiteral<{
readonly key: Type<number.divisibleBy<2>, {}>;
}, {}, bindThis<...>>) => Type<...> (+2 overloads)
type({
key: type.number.divisibleBy(2)
})
Equality
While embedded literal syntax is usually ideal for defining exact primitive values, the ===
operator, type.unit
and type.enumerated
can be helpful for defining a non-serializable reference like a symbol
or for deriving a type from a pre-existing list of allowed values.
const const mySymbol: typeof mySymbol
mySymbol = Symbol()
const const exactValue: Type<typeof mySymbol>
exactValue = type.unit(const mySymbol: typeof mySymbol
mySymbol)
const const exactValueFromSet: Type<true | 1337 | null>
exactValueFromSet = type.enumerated(1337, true, null)
const const mySymbol: typeof mySymbol
mySymbol = Symbol()
const const exactValue: Type<typeof mySymbol>
exactValue = const type: TypeParser
<readonly ["===", typeof mySymbol], Type<typeof mySymbol, {}>>(def: readonly ["===", ...unknown[]]) => Type<typeof mySymbol, {}> (+2 overloads)
type(["===", const mySymbol: typeof mySymbol
mySymbol])
const const exactValueFromSet: Type<true | 1337 | null>
exactValueFromSet = const type: TypeParser
<readonly ["===", 1337, true, null], Type<true | 1337 | null, {}>>(def: readonly ["===", ...unknown[]]) => Type<true | 1337 | null, {}> (+2 overloads)
type(["===", 1337, true, null])
const const mySymbol: typeof mySymbol
mySymbol = Symbol()
const const exactValue: Type<typeof mySymbol>
exactValue = const type: TypeParser
<"===", typeof mySymbol, readonly [], Type<typeof mySymbol, {}>>(_0: "===", _1: typeof mySymbol) => Type<typeof mySymbol, {}> (+2 overloads)
type("===", const mySymbol: typeof mySymbol
mySymbol)
const const exactValueFromSet: Type<true | 1337 | null>
exactValueFromSet = const type: TypeParser
<"===", 1337, readonly [true, null], Type<true | 1337 | null, {}>>(_0: "===", _1: 1337, _2_0: true, _2_1: null) => Type<true | 1337 | null, {}> (+2 overloads)
type("===", 1337, true, null)
Parenthetical
By default, ArkType’s operators follow the same precedence as TypeScript’s. Also like in TypeScript, this can be overridden by wrapping an expression in parentheses.
// hover to see the distinction!
const const groups: Type<{
stringOrArrayOfNumbers: string | number[];
arrayOfStringsOrNumbers: (string | number)[];
}>
groups = const type: TypeParser
<{
readonly stringOrArrayOfNumbers: "string | number[]";
readonly arrayOfStringsOrNumbers: "(string | number)[]";
}, Type<{
stringOrArrayOfNumbers: string | number[];
arrayOfStringsOrNumbers: (string | number)[];
}, {}>>(def: validateObjectLiteral<...>) => Type<...> (+2 overloads)
type({
stringOrArrayOfNumbers: "string | number[]",
arrayOfStringsOrNumbers: "(string | number)[]"
})
instanceof
Most builtin instance types like Array
and Date
are available directly as keywords, but instanceof
can be useful for constraining a type to one of your own classes.
class MyClass {}
const const instances: Type<MyClass>
instances = type.instanceOf(MyClass)
class MyClass {}
const const instances: Type<{
key: MyClass;
}>
instances = const type: TypeParser
<{
readonly key: readonly ["instanceof", typeof MyClass];
}, Type<{
key: MyClass;
}, {}>>(def: validateObjectLiteral<{
readonly key: readonly ["instanceof", typeof MyClass];
}, {}, bindThis<{
readonly key: readonly ["instanceof", typeof MyClass];
}>>) => Type<...> (+2 overloads)
type({
key: ["instanceof", MyClass]
})
class MyClass {}
const const instances: Type<{
key: MyClass;
}>
instances = const type: TypeParser
<{
readonly key: Type<MyClass, {}>;
}, Type<{
key: MyClass;
}, {}>>(def: validateObjectLiteral<{
readonly key: Type<MyClass, {}>;
}, {}, bindThis<{
readonly key: Type<MyClass, {}>;
}>>) => Type<...> (+2 overloads)
type({
key: const type: TypeParser
<"instanceof", typeof MyClass, readonly [], Type<MyClass, {}>>(_0: "instanceof", _1: typeof MyClass) => Type<MyClass, {}> (+2 overloads)
type("instanceof", MyClass)
})
Union
All unions are automatically discriminated to optimize check time and error message clarity.
const const unions: Type<{
key: string | number;
}>
unions = const type: TypeParser
<{
readonly key: "string | number";
}, Type<{
key: string | number;
}, {}>>(def: validateObjectLiteral<{
readonly key: "string | number";
}, {}, bindThis<{
readonly key: "string | number";
}>>) => Type<...> (+2 overloads)
type({
key: "string | number"
})
const const unions: Type<{
key: string | number;
}>
unions = const type: TypeParser
<{
readonly key: Type<string | number, {}>;
}, Type<{
key: string | number;
}, {}>>(def: validateObjectLiteral<{
readonly key: Type<string | number, {}>;
}, {}, bindThis<{
readonly key: Type<string | number, {}>;
}>>) => Type<...> (+2 overloads)
type({
key: type.string.or(type.number)
})
const const unions: Type<{
key: string | {
name: string;
};
}>
unions = const type: TypeParser
<{
readonly key: readonly ["string", "|", {
readonly name: "string";
}];
}, Type<{
key: string | {
name: string;
};
}, {}>>(def: validateObjectLiteral<{
readonly key: readonly ["string", "|", {
readonly name: "string";
}];
}, {}, bindThis<...>>) => Type<...> (+2 overloads)
type({
key: ["string", "|", { name: "string" }]
})
const const unions: Type<{
key: string | {
name: string;
};
}>
unions = const type: TypeParser
<{
readonly key: Type<string | {
name: string;
}, {}>;
}, Type<{
key: string | {
name: string;
};
}, {}>>(def: validateObjectLiteral<{
readonly key: Type<string | {
name: string;
}, {}>;
}, {}, bindThis<...>>) => Type<...> (+2 overloads)
type({
key: const type: TypeParser
<"string", "|", readonly [{
readonly name: "string";
}], Type<string | {
name: string;
}, {}>>(_0: "string", _1: "|", _2_0: validateObjectLiteral<{
readonly name: "string";
}, {}, bindThis<{
readonly name: "string";
}>>) => Type<...> (+2 overloads)
type("string", "|", { name: "string" })
})