Prop type definitions for Vue.js components with runtime validation and TypeScript support
—
The type definition system provides core utilities for creating, extending, and managing prop type definitions in Vue Types.
Core functions for creating Vue prop type definitions with validation and default value support.
/**
* Creates a basic Vue type definition with isRequired and def modifiers
* @param name - Internal name for the type (used in error messages)
* @param obj - Prop options object defining the type behavior
* @returns VueTypeDef with basic type definition methods
*/
function toType<T = any>(name: string, obj: PropOptions<T>): VueTypeDef<T>;
/**
* Creates a validatable Vue type definition with validate method
* @param name - Internal name for the type (used in error messages)
* @param obj - Prop options object defining the type behavior
* @returns VueTypeValidableDef with validation support
*/
function toValidableType<T = any>(
name: string,
obj: PropOptions<T>
): VueTypeValidableDef<T>;
// Prop options interface
interface PropOptions<T = any, D = T> {
type?: PropType<T> | true | null;
required?: boolean;
default?: D | DefaultFactory<D> | null | undefined | object;
validator?(value: unknown, props: Record<string, unknown>): boolean;
}Usage Examples:
import { toType, toValidableType } from "vue-types";
// Basic type definition
const basicString = toType('customString', {
type: String,
validator: (value) => typeof value === 'string'
});
// Validatable type definition
const validatableNumber = toValidableType('customNumber', {
type: Number
});
// Using the validate method
const positiveNumber = validatableNumber.validate((value) => value > 0);
// Custom type with complex validation
const emailType = toValidableType('email', {
type: String,
validator: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
});Utility for creating new types by extending existing type definitions.
/**
* Creates a new VueTypes type using another type as base
* @param name - Name of the new type
* @param source - Source type to extend from
* @param props - Additional properties to merge (optional)
* @returns New type definition with combined properties
*/
function fromType<T extends VueTypeDef<any>>(
name: string,
source: T
): T;
function fromType<
T extends VueTypeDef<any>,
V extends PropOptions<InferType<T>>
>(
name: string,
source: T,
props: V
): Omit<T, keyof V> & V;
// Type inference helper
type InferType<T> = T extends VueTypeDef<infer V> ? V : T;Usage Examples:
import { fromType, string, number } from "vue-types";
// Extend existing string type
const trimmedString = fromType('trimmedString', string(), {
validator: (value) => value.trim() === value
});
// Extend with additional properties
const positiveInteger = fromType('positiveInteger', number(), {
validator: (value) => Number.isInteger(value) && value > 0
});
// Chain extensions
const emailString = fromType('email', string(), {
validator: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
});
const requiredEmail = fromType('requiredEmail', emailString, {
required: true
});Function for validating values against prop type definitions at runtime.
/**
* Validates a given value against a prop type object
* @param type - Type definition or constructor to validate against
* @param value - Value to check for validity
* @param silent - If true, returns error string instead of logging warnings
* @returns true if valid, false if invalid (or error string in silent mode)
*/
function validateType<T, U>(
type: T,
value: U,
silent?: false
): boolean;
function validateType<T, U>(
type: T,
value: U,
silent: true
): string | boolean;Usage Examples:
import { validateType, string, number, shape } from "vue-types";
// Basic validation
const isValidString = validateType(string(), "hello"); // true
const isValidNumber = validateType(number(), "hello"); // false
// Silent mode for error details
const result = validateType(number(), "hello", true);
if (typeof result === 'string') {
console.log('Validation error:', result);
}
// Complex type validation
const userType = shape({
name: string().isRequired,
age: number()
});
const validUser = { name: "John", age: 30 };
const invalidUser = { name: "", age: "thirty" };
console.log(validateType(userType, validUser)); // true
console.log(validateType(userType, invalidUser)); // false
// Validate with context
const customType = {
validator: (value, props) => props.strict ? value > 100 : value > 0
};
validateType(customType, 50); // Depends on props contextFactory function for creating custom VueTypes classes with predefined default values.
/**
* Creates a new VueTypes class with custom default values
* @param defs - Partial default values for sensible defaults
* @returns New VueTypes class constructor with specified defaults
*/
function createTypes(defs?: Partial<VueTypesDefaults>): VueTypesInterface;
// Default values interface
interface VueTypesDefaults {
func: (...args: any[]) => any;
bool: boolean;
string: string;
number: number;
array: () => any[];
object: () => Record<string, any>;
integer: number;
}
// VueTypes interface
type VueTypesInterface = ReturnType<typeof createTypes>;Usage Examples:
import { createTypes } from "vue-types";
// Create VueTypes with custom defaults
const MyVueTypes = createTypes({
string: 'Default text',
number: -1,
bool: false,
array: () => ['default', 'items'],
object: () => ({ initialized: true })
});
// Use custom defaults
const titleProp = MyVueTypes.string; // Has default: 'Default text'
const countProp = MyVueTypes.number; // Has default: -1
const activeProp = MyVueTypes.bool; // Has default: false
// Create context-specific VueTypes
const ApiVueTypes = createTypes({
string: '',
number: 0,
array: () => [],
object: () => ({})
});
// Multiple instances with different defaults
const FormVueTypes = createTypes({
string: '',
bool: false,
number: 0
});
const GameVueTypes = createTypes({
number: 1,
bool: true,
array: () => []
});Core interfaces that define the structure and behavior of Vue type definitions.
// Base type definition interface
interface VueTypeBaseDef<T = unknown, D = DefaultType<T>, U = T>
extends PropOptions<T> {
_vueTypes_name: string;
type?: PropType<T>;
readonly def: (def?: D) => this & { default: U };
readonly isRequired: this & { required: true };
}
// Basic type definition (non-validatable)
interface VueTypeDef<T = unknown> extends VueTypeBaseDef<T> {}
// Validatable type definition with validate method
interface VueTypeValidableDef<T = unknown, V = ValidatorFunction<T>>
extends VueTypeBaseDef<T> {
readonly validate: (fn: V) => this & { validator: V };
}
// Shape-specific 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;
}
// Utility types
type ValidatorFunction<T> = (
value: T,
props?: Record<string, unknown>
) => boolean;
type DefaultType<T> = T extends NativeType ? T : DefaultFactory<T>;
type DefaultFactory<T> = (() => T) | T;
type NativeType = string | boolean | number | null | undefined | Function;Create reusable type builders for common patterns:
import { toValidableType, validateType } from "vue-types";
// URL type builder
function createUrlType(name: string) {
return toValidableType<string>(name, {
type: String,
validator: (value) => {
try {
new URL(value);
return true;
} catch {
return false;
}
}
});
}
// Range type builder
function createRangeType(name: string, min: number, max: number) {
return toValidableType<number>(name, {
type: Number,
validator: (value) => value >= min && value <= max
});
}
// Usage
const urlProp = createUrlType('websiteUrl');
const percentageProp = createRangeType('percentage', 0, 100);Combine multiple validation functions for complex requirements:
import { fromType, string } from "vue-types";
// Create base types
const nonEmptyString = fromType('nonEmpty', string(), {
validator: (value) => value.length > 0
});
const trimmedString = fromType('trimmed', nonEmptyString, {
validator: (value) => value.trim() === value
});
const alphanumericString = fromType('alphanumeric', trimmedString, {
validator: (value) => /^[a-zA-Z0-9]+$/.test(value)
});
// Final validated type combines all requirements
const usernameType = fromType('username', alphanumericString, {
validator: (value) => value.length >= 3 && value.length <= 20
});Use type system utilities with Vue components:
import { createTypes, validateType } from "vue-types";
// Create domain-specific types
const ApiTypes = createTypes({
string: '',
number: 0,
bool: false
});
// Component with validation helpers
export default {
props: {
endpoint: ApiTypes.string.isRequired,
timeout: ApiTypes.number.def(5000),
retries: ApiTypes.number.validate((value) => value >= 0).def(3)
},
methods: {
validateEndpoint(url: string) {
return validateType(ApiTypes.string, url, true);
},
isValidTimeout(ms: number) {
return validateType(
ApiTypes.number.validate((value) => value > 0),
ms
);
}
}
};Leverage the type system for runtime validation beyond props:
import { validateType, shape, string, number, arrayOf } from "vue-types";
// Define API response shape
const apiResponseType = shape({
data: arrayOf(shape({
id: number().isRequired,
name: string().isRequired,
email: string()
})),
status: string().isRequired,
message: string()
});
// Validate API responses
async function fetchUsers() {
const response = await fetch('/api/users');
const data = await response.json();
// Runtime validation
const isValid = validateType(apiResponseType, data, true);
if (typeof isValid === 'string') {
throw new Error(`Invalid API response: ${isValid}`);
}
return data;
}Install with Tessl CLI
npx tessl i tessl/npm-vue-types