TypeScript Usage
VueTypes is written in TypeScript and comes with built-in types support.
props: {
// prop type is `string`
name: string(),
// ERROR: Argument of type 'boolean' is not assignable to parameter of type 'string'
surname: string().def(false),
}
Optional Type Constraint
Some validators accept an optional type argument to refine their TypeScript typing.
any<T = any>
props: {
unknownProp: any<unknown>()
}
string<T = string>
Accepts both strings and enums.
props: {
// use a union type to constrain the string type
color: string<'red' | 'green'>()
}
enum Colors {
red = 'red'
green = 'green'
}
props: {
// same as above, but with an enum
color: string<Colors>()
}
TIP
The same prop type can be expressed using oneOf
, which also performs validation at runtime:
props: {
genre: oneOf(['red', 'green'] as const)
}
number<T = number> and integer<T = number>
props: {
// use a union type to constrain the number type
count: number<1 | 2>()
countInt: integer<1 | 2>()
}
func<T = (...args: any[]) => any>
Useful for typing event handlers and function return types.
type EventFn = (e: Event) => void
type AsyncFn = () => Promise<string[]>
props: {
onClick: fn<EventFn>()
loadStrings: fn<AsyncFn>()
}
object<T = { [key: string]: any }>
interface User {
name: string
// ...
}
props: {
user: object<User>()
}
TIP
You can use shape
to have both compile-time and runtime validation:
interface User {
name: string
// ...
}
props: {
user: shape<User>({
name: string().isRequired,
})
}
array<T = unknown>
The validator accepts an argument defining the type of the array's items.
interface User {
name: string
// ...
}
props: {
// array of numbers
sizes: array<number>()
// array of users
users: array<User>()
}
TIP
The same prop types can be expressed using arrayOf
, which also performs validation at runtime:
interface User {
name: string
// ...
}
props: {
// array of numbers
sizes: arrayOf(number())
// array of users
users: arrayOf(shape<User>({ name: string().isRequired }))
}
OneOfType<T>
You can use a union type to specify the expected types.
interface User {
name: string
// ...
}
props: {
// string or instance of User
theProp: oneOfType<string | User>([String, Object])
}
TIP
The same prop types can be expressed by composing VueTypes validators:
interface User {
name: string
// ...
}
props: {
// string or instance of User
theProp: oneOfType([string(), object<User>()])
}
shape<T>
Setting the type argument provides type checking on top of runtime validation:
interface User {
name: string
id?: string
}
props: {
user: shape<User>({
name: string().isRequired,
id: string(),
})
}
custom<T>
You can define the type of the value received by the validator function.
props: {
// function argument is of type string
nonEmptyString: custom<string>((v) => typeof v === 'string' && v.length > 0)
}
TIP
This validator can be used for tuple props:
type Pair = [string, number]
props: {
tuple: custom<Pair>(
([a, b]) => typeof a === 'string' && typeof b === 'number',
)
}
oneOf
You can use const assertions on the expected values to constrain the validator's type:
props: {
// ERROR: Argument of type '"small"' is not assignable
// to parameter of type '"large" | "medium"'.
sizes: oneOf(['large', 'medium'] as const).def('small')
}
Alternatively, you can pass a union type:
props: {
// Same (mostly) as above
// see below for details
sizes: oneOf<'large' | 'medium'>(['large', 'medium'])
}
WARNING
Note that union types don't put any constraints on the presence of all their members in the validation array. This can lead to runtime bugs not detected by the type checker:
props: {
// TS type checker does not report any error
// but Vue runtime throws an error
sizes: oneOf<'large' | 'medium'>(['large']).def('medium')
}
As a general rule, we strongly suggest using const assertions whenever possible.
props: {
// type checker and runtime error
sizes: oneOf(['large'] as const).def('medium')
}