JavaScript作为弱类型动态语言,运行时不会强制校验变量类型,很多场景下我们需要自行实现类型系统来约束数据格式,避免类型错误导致的异常。实现类型系统首先需要对JS的基础类型有清晰认知,再基于类型判断能力构建校验规则。

JS基础类型与判断方法
JS的基础类型分为原始类型和引用类型,不同类型的判断需要用到不同的方法,这是实现类型系统的基础。
基础类型分类
- 原始类型:string、number、boolean、null、undefined、symbol、bigint
- 引用类型:object、array、function、date、regexp等
常用类型判断方法
最基础的类型判断可以使用typeof操作符,但它对null和引用类型的判断存在局限性:
// typeof 判断示例
console.log(typeof "hello"); // string
console.log(typeof 123); // number
console.log(typeof true); // boolean
console.log(typeof null); // object 存在历史遗留问题
console.log(typeof []); // object 无法区分数组和普通对象
console.log(typeof function() {}); // function 可以识别函数类型
如果需要更精准的类型判断,可以使用Object.prototype.toString方法,它能返回准确的类型标识:
// 精准类型判断函数
function getType(target) {
const typeStr = Object.prototype.toString.call(target);
// 返回格式为 [object Type],提取Type部分
return typeStr.slice(8, -1).toLowerCase();
}
console.log(getType("hello")); // string
console.log(getType(123)); // number
console.log(getType(null)); // null
console.log(getType([])); // array
console.log(getType({})); // object
console.log(getType(new Date())); // date
简单类型系统的实现思路
实现一个基础的类型系统,核心需要包含类型定义、类型校验、错误提示三个部分。我们可以先定义一个类型规则的描述方式,再编写校验函数执行检查。
定义类型规则
我们可以约定类型规则为对象形式,支持基础类型和自定义复合类型:
// 基础类型规则定义
const typeRules = {
string: (val) => getType(val) === "string",
number: (val) => getType(val) === "number" && !isNaN(val),
boolean: (val) => getType(val) === "boolean",
array: (val) => getType(val) === "array",
object: (val) => getType(val) === "object" && val !== null,
// 自定义复合类型:用户对象
user: (val) => {
return getType(val) === "object" &&
getType(val.name) === "string" &&
getType(val.age) === "number"
}
};
实现类型检查函数
基于类型规则,我们可以编写通用的类型检查函数,支持传入值和对应的类型规则名,返回校验结果和错误信息:
/**
* 类型检查函数
* @param {any} value 待检查的值
* @param {string} typeName 类型规则名
* @returns {Object} 包含isValid和error信息的对象
*/
function checkType(value, typeName) {
const rule = typeRules[typeName];
if (!rule) {
return {
isValid: false,
error: `不存在名为${typeName}的类型规则`
};
}
const isValid = rule(value);
return {
isValid,
error: isValid ? "" : `值${value}不符合${typeName}类型要求`
};
}
// 测试示例
const testUser = { name: "张三", age: 20 };
const result1 = checkType(testUser, "user");
console.log(result1); // { isValid: true, error: "" }
const result2 = checkType("hello", "number");
console.log(result2); // { isValid: false, error: "值hello不符合number类型要求" }
进阶:支持嵌套结构的类型检查
实际场景中很多数据结构是嵌套的,比如对象包含子对象、数组包含对象元素,我们需要扩展类型系统支持嵌套校验。
扩展类型规则定义
我们可以让类型规则支持对象结构的描述,每个字段对应自己的类型规则:
// 扩展类型规则,支持对象结构定义
const advancedTypeRules = {
// 基础类型规则
string: (val) => getType(val) === "string",
number: (val) => getType(val) === "number" && !isNaN(val),
// 数组类型规则,支持定义数组元素的类型
array: (val, itemType) => {
if (getType(val) !== "array") return false;
// 如果指定了元素类型,校验每个元素
if (itemType) {
return val.every(item => checkAdvancedType(item, itemType).isValid);
}
return true;
},
// 对象类型规则,支持定义对象每个字段的类型
object: (val, shape) => {
if (getType(val) !== "object" || val === null) return false;
// 如果指定了结构,校验每个字段
if (shape) {
return Object.keys(shape).every(key => {
return checkAdvancedType(val[key], shape[key]).isValid;
});
}
return true;
}
};
实现嵌套类型检查函数
/**
* 进阶类型检查函数,支持嵌套结构
* @param {any} value 待检查的值
* @param {Object|string} typeRule 类型规则,可以是基础类型字符串,或者是带参数的规则对象
* @returns {Object} 校验结果
*/
function checkAdvancedType(value, typeRule) {
// 如果是基础类型字符串,直接调用对应规则
if (getType(typeRule) === "string") {
const rule = advancedTypeRules[typeRule];
if (!rule) {
return { isValid: false, error: `不存在${typeRule}类型规则` };
}
const isValid = rule(value);
return {
isValid,
error: isValid ? "" : `值不符合${typeRule}类型要求`
};
}
// 如果是对象形式的规则,解析类型和参数
if (getType(typeRule) === "object") {
const { type, params } = typeRule;
const rule = advancedTypeRules[type];
if (!rule) {
return { isValid: false, error: `不存在${type}类型规则` };
}
const isValid = rule(value, params);
return {
isValid,
error: isValid ? "" : `值不符合${type}类型要求`
};
}
return { isValid: false, error: "无效的类型规则" };
}
// 测试嵌套结构
const userListRule = {
type: "array",
params: {
type: "object",
params: {
name: "string",
age: "number",
hobbies: { type: "array", params: "string" }
}
}
};
const testData = [
{ name: "张三", age: 20, hobbies: ["篮球", "足球"] },
{ name: "李四", age: 22, hobbies: ["读书"] }
];
const result = checkAdvancedType(testData, userListRule);
console.log(result); // { isValid: true, error: "" }
const badData = [
{ name: "王五", age: "20", hobbies: ["跑步"] }
];
const badResult = checkAdvancedType(badData, userListRule);
console.log(badResult); // { isValid: false, error: "值不符合object类型要求" }
类型检查的常见使用场景
实现好的类型系统可以在很多场景发挥作用:
- 函数参数校验:在函数入口处校验入参类型,避免不符合预期的参数进入逻辑
- 接口数据校验:请求接口拿到数据后,先校验数据格式是否符合预期,再进行后续处理
- 配置项校验:校验用户传入的配置项是否符合要求,给出清晰的错误提示
需要注意的是,JS中实现的类型系统是运行时的类型检查,无法像TypeScript那样在编译阶段发现类型错误,但是可以在运行时提前拦截类型异常,减少线上问题的发生概率。
JavaScript类型系统类型检查类型判断修改时间:2026-06-14 04:54:24