如何正确实现支持单个/数组类型参数的TypeScript函数?
正确实现方案
你的代码问题在于:TypeScript无法通过单独判断index是否为数组,来推断type的类型也会对应匹配——两个联合类型参数是独立的,可能出现一个是数组、一个不是的参数组合,导致逻辑错误和类型校验失败。
下面提供两种可靠的实现方式:
方式一:函数重载(推荐)
通过重载签名明确限定参数的两种合法组合,让TypeScript能准确推断参数类型:
// 单个参数的重载签名 function updateNodeTypeByIndex(index: Vec2, type: NodeType): void; // 数组参数的重载签名 function updateNodeTypeByIndex(index: Vec2[], type: NodeType[]): void; // 实际实现签名 function updateNodeTypeByIndex(index: Vec2 | Vec2[], type: NodeType | NodeType[]): void { if (Array.isArray(index) && Array.isArray(type)) { // 数组参数逻辑:此时index是Vec2[],type是NodeType[] index.forEach((pos, idx) => { // 示例:根据数组中的每个索引更新对应节点类型 // updateNode(pos, type[idx]); }); } else if (!Array.isArray(index) && !Array.isArray(type)) { // 单个参数逻辑:此时index是Vec2,type是NodeType // updateNode(index, type); } else { // 处理参数不匹配的非法情况 throw new Error("参数错误:index和type必须同时为数组或同时为单个值"); } }
方式二:自定义类型守卫
通过自定义类型谓词,同时校验两个参数的类型一致性:
// 自定义类型守卫:判断两个参数均为数组 function isArrayPair( index: Vec2 | Vec2[], type: NodeType | NodeType[] ): index is Vec2[] & type is NodeType[] { return Array.isArray(index) && Array.isArray(type); } // 自定义类型守卫:判断两个参数均为单个值 function isSinglePair( index: Vec2 | Vec2[], type: NodeType | NodeType[] ): index is Vec2 & type is NodeType { return !Array.isArray(index) && !Array.isArray(type); } const updateNodeTypeByIndex = (index: Vec2 | Vec2[], type: NodeType | NodeType[]) => { if (isArrayPair(index, type)) { // 数组参数逻辑 } else if (isSinglePair(index, type)) { // 单个参数逻辑 } else { throw new Error("参数错误:index和type的类型必须匹配"); } }
注意:优先使用Array.isArray而非instanceof Array,前者是更可靠的数组判断方式,不受原型链修改的影响。
内容的提问来源于stack exchange,提问作者Ammar Ahmed
相关产品推荐
相关产品推荐

