Prop type definitions for Vue.js components with runtime validation and TypeScript support
—
Complex validators provide advanced validation patterns for custom types, enums, collections, and structured objects.
Creates validators with user-defined validation functions for complex business logic.
/**
* Creates a custom validator with user-defined validation function
* @param validatorFn - Function that returns true if value is valid
* @param warnMsg - Optional custom warning message on validation failure
* @returns VueTypeDef with custom validation logic
*/
static custom<T>(
validatorFn: ValidatorFunction<T>,
warnMsg?: string
): VueTypeDef<T>;
// Standalone function
function custom<T>(
validatorFn: ValidatorFunction<T>,
warnMsg?: string
): VueTypeDef<T>;
// Validator function signature
type ValidatorFunction<T> = (
value: T,
props?: Record<string, unknown>
) => boolean;Usage Examples:
import VueTypes, { custom } from "vue-types";
// Email validation
const email = custom<string>(
(value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value),
'must be a valid email address'
);
// Range validation
const percentage = custom<number>(
(value) => value >= 0 && value <= 100,
'must be between 0 and 100'
);
// Complex object validation
const userProfile = custom<{ name: string; age: number }>(
(value) => value.name.length > 0 && value.age >= 0,
'invalid user profile'
);
// Usage in component
export default {
props: {
userEmail: email.isRequired,
completion: percentage.def(0),
profile: userProfile.isRequired
}
};Validates that a value is one of a specific set of allowed values (enum-style validation).
/**
* Creates a validator that accepts only specific values
* @param arr - Array of allowed values
* @returns VueTypeDef that accepts only values from the array
*/
static oneOf<T extends readonly any[]>(arr: T): VueTypeDef<T[number]>;
// Standalone function
function oneOf<D, T extends readonly D[]>(arr: T): VueTypeDef<T[number]>;Usage Examples:
import VueTypes, { oneOf } from "vue-types";
// String enum
const status = oneOf(['pending', 'success', 'error'] as const);
const theme = oneOf(['light', 'dark', 'auto'] as const);
// Mixed types
const priority = oneOf([1, 2, 3, 'high', 'low'] as const);
// With symbols
const eventType = oneOf([Symbol('click'), Symbol('hover')] as const);
// Usage in component
export default {
props: {
currentStatus: status.def('pending'),
appTheme: theme.isRequired,
taskPriority: priority.def(1)
}
};Validates that a value matches one of multiple type definitions.
/**
* Creates a validator that accepts values matching any of multiple types
* @param arr - Array of type definitions to match against
* @returns VueTypeDef that accepts values matching any provided type
*/
static oneOfType<T extends VueProp<any>[]>(
arr: T
): VueTypeDef<InferType<T[number]>>;
// Standalone function
function oneOfType<D extends V, U extends VueProp<any>, V = InferType<U>>(
arr: U[]
): VueTypeDef<D>;Usage Examples:
import VueTypes, { oneOfType, string, number, object } from "vue-types";
// String or number
const stringOrNumber = oneOfType([string(), number()]);
// Complex type union
const idValue = oneOfType([
string(),
number(),
object<{ type: string; value: any }>()
]);
// With Vue native types
const mixedInput = oneOfType([
String,
Number,
VueTypes.shape({ label: string(), value: string() })
]);
// Usage in component
export default {
props: {
id: stringOrNumber.isRequired,
value: idValue.def(''),
input: mixedInput.isRequired
}
};Validates arrays where all elements match a specific type definition.
/**
* Creates a validator for arrays with typed elements
* @param type - Type definition that all array elements must match
* @returns VueTypeDef for arrays of the specified type
*/
static arrayOf<T extends VueProp<any>>(type: T): VueTypeDef<InferType<T>[]>;
// Standalone function
function arrayOf<T extends VueProp<any>>(type: T): VueTypeDef<InferType<T>[]>;Usage Examples:
import VueTypes, { arrayOf, string, number, shape } from "vue-types";
// Array of strings
const tags = arrayOf(string());
const categories = arrayOf(VueTypes.string);
// Array of numbers
const scores = arrayOf(number()).def(() => []);
// Array of objects
const users = arrayOf(shape({
name: string().isRequired,
age: number(),
email: string()
}));
// Nested arrays
const matrix = arrayOf(arrayOf(number()));
// Usage in component
export default {
props: {
postTags: tags.def(() => []),
testScores: scores.isRequired,
userList: users.def(() => []),
numberMatrix: matrix.def(() => [])
}
};Validates objects where all property values match a specific type definition.
/**
* Creates a validator for objects with typed property values
* @param type - Type definition that all object values must match
* @returns VueTypeDef for objects with values of the specified type
*/
static objectOf<T extends VueProp<any>>(
type: T
): VueTypeDef<Record<string, InferType<T>>>;
// Standalone function
function objectOf<T extends VueProp<any>>(
type: T
): VueTypeDef<Record<string, InferType<T>>>;Usage Examples:
import VueTypes, { objectOf, string, number, arrayOf } from "vue-types";
// Object with string values
const translations = objectOf(string());
// Object with number values
const scores = objectOf(number()).def(() => ({}));
// Object with complex values
const userPreferences = objectOf(arrayOf(string()));
// Nested structure
const categoryItems = objectOf(objectOf(string()));
// Usage in component
export default {
props: {
i18n: translations.isRequired,
gameScores: scores.def(() => ({})),
preferences: userPreferences.def(() => ({})),
catalog: categoryItems.def(() => ({}))
}
};Validates that values are instances of a specific constructor function or class.
/**
* Creates a validator for class instances
* @param instanceConstructor - Constructor function to validate against
* @returns VueTypeDef for instances of the specified constructor
*/
static instanceOf<C extends Constructor>(
instanceConstructor: C
): VueTypeDef<InstanceType<C>>;
// Standalone function
function instanceOf<C extends Constructor>(
instanceConstructor: C
): VueTypeDef<InstanceType<C>>;
// Constructor type
type Constructor = new (...args: any[]) => any;Usage Examples:
import VueTypes, { instanceOf } from "vue-types";
// Built-in classes
const timestamp = instanceOf(Date);
const pattern = instanceOf(RegExp);
const errorInstance = instanceOf(Error);
// Custom classes
class User {
constructor(public name: string, public id: number) {}
}
class ApiClient {
constructor(private baseUrl: string) {}
}
const user = instanceOf(User);
const client = instanceOf(ApiClient);
// Usage in component
export default {
props: {
createdAt: timestamp.isRequired,
validator: pattern.def(() => /.*/),
currentUser: user.isRequired,
apiClient: client.isRequired
}
};Validates object structure with defined property types and supports loose validation.
/**
* Creates a validator for objects with specific structure
* @param obj - Object defining the required structure and property types
* @returns VueTypeShape with strict validation and loose mode support
*/
static shape<T extends object>(obj: {
[K in keyof T]: Prop<T[K]> | VueProp<T[K]>
}): VueTypeShape<T>;
// Standalone function
function shape<T extends object>(obj: {
[K in keyof T]: Prop<T[K]> | VueProp<T[K]>
}): VueTypeShape<T>;
// Shape interfaces
interface VueTypeShape<T> extends VueTypeBaseDef<T> {
readonly loose: VueTypeLooseShape<T>;
}
interface VueTypeLooseShape<T> extends VueTypeBaseDef<T> {
readonly loose: VueTypeLooseShape<T>;
readonly _vueTypes_isLoose: true;
}Usage Examples:
import VueTypes, { shape, string, number, bool, arrayOf } from "vue-types";
// Basic object shape
const userShape = shape({
name: string().isRequired,
age: number(),
email: string()
});
// Nested shapes
const addressShape = shape({
street: string().isRequired,
city: string().isRequired,
zipCode: string(),
country: string().def('US')
});
const userWithAddress = shape({
name: string().isRequired,
address: addressShape.isRequired,
isActive: bool().def(true)
});
// Shape with arrays
const blogPost = shape({
title: string().isRequired,
content: string().isRequired,
tags: arrayOf(string()).def(() => []),
publishedAt: VueTypes.instanceOf(Date)
});
// Loose shape (allows additional properties)
const flexibleConfig = shape({
theme: string().def('light'),
debug: bool().def(false)
}).loose;
// Usage in component
export default {
props: {
user: userShape.isRequired,
profile: userWithAddress.def(() => ({
name: '',
address: { street: '', city: '' },
isActive: true
})),
post: blogPost.isRequired,
settings: flexibleConfig.def(() => ({ theme: 'light', debug: false }))
}
};Complex validation scenarios can be achieved by combining different validators:
// Union of specific shapes
const notificationSettings = oneOfType([
shape({
type: oneOf(['email'] as const),
address: string().isRequired
}),
shape({
type: oneOf(['sms'] as const),
phone: string().isRequired
}),
shape({
type: oneOf(['push'] as const),
deviceId: string().isRequired
})
]);
// Conditional validation
const conditionalField = custom<any>((value, props) => {
if (props?.requiresValidation) {
return typeof value === 'string' && value.length > 0;
}
return true;
});Complex validators provide detailed error messages for debugging:
// Custom error messages
const strongPassword = custom<string>(
(value) => {
return value.length >= 8 &&
/[A-Z]/.test(value) &&
/[a-z]/.test(value) &&
/\d/.test(value);
},
'password must be at least 8 characters with uppercase, lowercase, and numbers'
);
// Shape validation shows specific property errors
const userProfile = shape({
username: string().validate((value) => value.length >= 3),
email: custom<string>((value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value))
});Complex validators maintain full type safety:
// Inferred types
const user = shape({
name: string(),
age: number(),
isActive: bool()
});
// TypeScript infers: VueTypeShape<{ name: string; age: number; isActive: boolean }>
// Generic constraints
const apiResponse = shape({
data: custom<User[]>((value) => Array.isArray(value)),
status: oneOf(['success', 'error'] as const),
message: string()
});Install with Tessl CLI
npx tessl i tessl/npm-vue-types