Generics

Keywords

Record is now available as a builtin keyword.

import { type } from "arktype"

const  = type("Record<string, string>")

In addition to Record, the following generics from TS are now available in ArkType:

  • Pick
  • Omit
  • Extract
  • Exclude

These can be instantiated in one of three ways:

import { type, type Type } from "arktype"

const  = <T extends string>(of: type.Any<T>) =>
	type({
		box: of
	})

const  = (type("string"))

// @ts-expect-error
const  = (type("number"))

console.log(boxType({ box: 5 }).toString())
console.log(boxType({ box: "foo" }))

Syntax

Definition

import { type } from "arktype"

const  = type("<t>", { box: "t" })

// hover me!
const  = ({ cat: { isAlive: "boolean" } })

Constrained Parameters

All syntax in parameters definitions and all references to generic args are fully-type safe and autocompleted like any builtin keyword. Constraints can be used just like TS to limit what can be passed to a generic and allow that arg to be used with operators like >.

import { type } from "arktype"

const  = type("<arr extends unknown[]>", "arr > 0")

const  = ("number[]")

Scoped

There is a special syntax for specifying generics in a scope:

import { scope } from "arktype"

const  = scope({
	"box<t, u>": {
		box: "t | u"
	},
	bitBox: "box<0, 1>"
}).export()

const  = .bitBox({ box: 0 })

Invocation

import { type } from "arktype"

const  = type("Extract<0 | 1, 1>")
Chained
import { type } from "arktype"

const  = type({
	name: "string",
	"age?": "number",
	isAdmin: "boolean"
})

// hover me!
const  = .pick("name", "age")

Invoked

import { type } from "arktype"

const  = type.keywords.Exclude("boolean", "false")

HKT

Our new generics have been built using a new method for integrating arbitrary external types as native ArkType generics! This opens up tons of possibilities for external integrations that would otherwise not be possible. As a preview, here's what the implementation of Partial looks like internally:

import { generic, Hkt } from "arktype"

const  = generic(["T", "object"])(
	args => args.T.partial(),
	class PartialHkt extends Hkt<[object]> {
		declare body: <this[0]>
	}
)

Recursive and cyclic generics are also currently unavailable and will be added soon.

For more usage examples, check out the unit tests for generics here.

This feature was built to be very robust and flexible. We're excited to see what you do with it!

On this page