Skip to content

API

Keywords

const 
const keywords: Type<{
    string: string;
    date: Date;
    dateFormattedString: string.date;
    isoFormattedString: string.date.iso;
    transformStringToDate: (In: string.date) => To<Date>;
}>
keywords
=
const type: TypeParser
<{
    readonly string: "string";
    readonly date: "Date";
    readonly dateFormattedString: "string.date";
    readonly isoFormattedString: "string.date.iso";
    readonly transformStringToDate: "string.date.parse";
}, Type<...>>(def: validateObjectLiteral<...>) => Type<...> (+2 overloads)
type
({
string: "string", date: "Date", // Subtype keywords refine or transform their root type. dateFormattedString: "string.date", isoFormattedString: "string.date.iso", transformStringToDate: "string.date.parse" })

Literals

const 
const literals: Type<{
    number: 1337;
    bigint: 1337n;
    string: {
        singleQuoted: "typescript";
        doubleQuoted: "arktype";
    };
    date: {
        singleQuoted: Date.literal<"01-01-1970">;
        doubleQuoted: Date.literal<"01-01-1970">;
    };
    keywords: [true, false, null, undefined];
}>
literals
=
const type: TypeParser
<{
    readonly number: "1337";
    readonly bigint: "1337n";
    readonly string: {
        readonly singleQuoted: "'typescript'";
        readonly doubleQuoted: "\"arktype\"";
    };
    readonly date: {
        readonly singleQuoted: "d'01-01-1970'";
        readonly doubleQuoted: "d\"01-01-1970\"";
    };
    readonly keywords: readonly [...];
}, Type<...>>(def: validateObjectLiteral<...>) => Type<...> (+2 overloads)
type
({
number: "1337", bigint: "1337n", string: { singleQuoted: "'typescript'", doubleQuoted: '"arktype"' }, date: { // Date literals represent a Date instance with an exact value. // They're primarily useful in ranges (see below). singleQuoted: "d'01-01-1970'", doubleQuoted: 'd"01-01-1970"' }, keywords: ["true", "false", "null", "undefined"] })

Objects

const const symbolicKey: typeof symbolicKeysymbolicKey = Symbol()

const 
const object: Type<{
    [x: string]: string;
    requiredKey: string;
    [symbolicKey]: {
        nested: unknown;
    };
    optionalKey?: string.uuid;
}>
object
=
const type: TypeParser
<{
    readonly requiredKey: "string";
    readonly "optionalKey?": "string.uuid";
    readonly [symbolicKey]: {
        readonly nested: "unknown";
    };
    readonly "[string]": "string";
}, Type<{
    [x: string]: string;
    requiredKey: string;
    [symbolicKey]: {
        ...;
    };
    optionalKey?: string.uuid;
}, {}>>(def: validateObjectLiteral<...>) => Type<...> (+2 overloads)
type
({
requiredKey: "string", "optionalKey?": "string.uuid", // Nested definitions don't require additional `type` calls. [const symbolicKey: typeof symbolicKeysymbolicKey]: { nested: "unknown" }, // Index signatures are unlabeled and support arbitrary expressions. "[string]": "string" })

Kitchen Sink (more comprehensive docs to come next week!)

export const 
const currentTsSyntax: Type<{
    keyword: null;
    stringLiteral: "TS";
    numberLiteral: 5;
    bigintLiteral: 5n;
    union: string | number;
    intersection: true;
    array: Date[];
    grouping: (0 | 1)[];
    objectLiteral: {
        nested: string;
        optional?: number;
    };
    arrayOfObjectLiteral: {
        name: string;
    }[];
    tuple: [number, number];
    keyof: never;
    variadicTuples: [true, ...false[]];
    arrayOfObjectLiteralChained: {
        name: string;
    }[];
}>
currentTsSyntax
=
const type: TypeParser
<{
    readonly keyword: "null";
    readonly stringLiteral: "'TS'";
    readonly numberLiteral: "5";
    readonly bigintLiteral: "5n";
    readonly union: "string|number";
    readonly intersection: "boolean&true";
    ... 7 more ...;
    readonly arrayOfObjectLiteralChained: Type<...>;
}, Type<...>>(def: validateObjectLiteral<...>) => Type<...> (+2 overloads)
type
({
keyword: "null", stringLiteral: "'TS'", numberLiteral: "5", bigintLiteral: "5n", union: "string|number", intersection: "boolean&true", array: "Date[]", grouping: "(0|1)[]", objectLiteral: { nested: "string", "optional?": "number" }, arrayOfObjectLiteral: [ { name: "string" }, "[]" ], tuple: ["number", "number"], keyof: "keyof object", variadicTuples: ["true", "...", "false[]"], arrayOfObjectLiteralChained:
const type: TypeParser
<{
    readonly name: "string";
}, Type<{
    name: string;
}, {}>>(def: validateObjectLiteral<{
    readonly name: "string";
}, {}, bindThis<{
    readonly name: "string";
}>>) => Type<...> (+2 overloads)
type
({ name: "string" }).array()
})

Constraints

// runtime-specific syntax and builtin keywords with great error messages

export const 
const validationSyntax: Type<{
    keywords: string.email | string.uuid | string.creditCard | integer;
    builtinParsers: (In: string.date) => To<Date>;
    nativeRegexLiteral: string.matching<string>;
    embeddedRegexLiteral: of<string, Predicate<"email"> & Matching<"@arktype\\.io">>;
    divisibility: number.divisibleBy<10>;
    bound: string.is<MoreThanLength<10> & Predicate<"alpha">>;
    range: of<string.email[], LessThanLength<100> & AtLeastLength<1>>;
    narrows: number.branded<"?">;
    morphs: (In: string) => Out<number>;
}>
validationSyntax
=
const type: TypeParser
<{
    readonly keywords: "string.email | string.uuid | string.creditCard | number.integer";
    readonly builtinParsers: "string.date.parse";
    readonly nativeRegexLiteral: RegExp;
    ... 5 more ...;
    readonly morphs: readonly [...];
}, Type<...>>(def: validateObjectLiteral<...>) => Type<...> (+2 overloads)
type
({
keywords: "string.email | string.uuid | string.creditCard | number.integer", // and many more builtinParsers: "string.date.parse", // parses a Date from a string nativeRegexLiteral: /@arktype\.io/, embeddedRegexLiteral: "string.email & /@arktype\\.io/", divisibility: "number % 10", // a multiple of 10 bound: "string.alpha > 10", // an alpha-only string with more than 10 characters range: "1 <= string.email[] < 100", // a list of 1 to 99 emails narrows: ["number", ":", n => n % 2 === 1], // an odd integer morphs: ["string", "=>", parseFloat] // validates a string input then parses it to a number }) // root-level expressions const
const intersected: Type<{
    value: string;
    format: "bigint";
}>
intersected
=
const type: TypeParser
<{
    readonly value: "string";
}, "&", readonly [{
    readonly format: "'bigint'";
}], Type<{
    value: string;
    format: "bigint";
}, {}>>(_0: validateObjectLiteral<{
    readonly value: "string";
}, {}, bindThis<{
    readonly value: "string";
}>>, _1: "&", _2_0: validateObjectLiteral<...>) => Type<...> (+2 overloads)
type
({ value: "string" }, "&", { format: "'bigint'" })
// chained expressions via .or, .and, .narrow, .pipe and much more // (these replace previous helper methods like union and intersection) const
const user: Type<{
    name: string;
    age: number;
}>
user
=
const type: TypeParser
<{
    readonly name: "string";
    readonly age: "number";
}, Type<{
    name: string;
    age: number;
}, {}>>(def: validateObjectLiteral<{
    readonly name: "string";
    readonly age: "number";
}, {}, bindThis<{
    readonly name: "string";
    readonly age: "number";
}>>) => Type<...> (+2 overloads)
type
({
name: "string", age: "number" }) // type is fully introspectable and traversable const
const parseUser: Type<(In: string) => To<{
    name: string;
    age: number;
}>>
parseUser
=
const type: TypeParser
<"string", Type<string, {}>>(def: "string") => Type<string, {}> (+2 overloads)
type
("string").pipe(s => JSON.parse(s),
const user: Type<{
    name: string;
    age: number;
}>
user
)
const
const maybeMe: ArkErrors | {
    name: string;
    age: number;
}
maybeMe
= parseUser('{ "name": "David" }')
if (
const maybeMe: ArkErrors | {
    name: string;
    age: number;
}
maybeMe
instanceof type.errors) {
// "age must be a number (was missing)" console.log(const maybeMe: ArkErrorsmaybeMe.summary) }