Typescript中如何实现可同时断言多个值的类型检查函数?
解决方案
TS 本身不支持直接在返回值中声明多个独立的类型谓词,但有两种极简的实现方案,不需要引入可辨识联合的额外复杂度:
方案1:元组类型守卫实现多参数同时断言
将两个入参打包为元组,直接断言整个元组的类型,即可同时收敛两个变量的类型:
// 类型守卫定义 function isMulti(tuple: [multiple: boolean, value: string | string[]]): tuple is [true, string[]] { return tuple[0] && Array.isArray(tuple[1]) } // 使用示例 let multiple: boolean let value: string[] | string if (isMulti([multiple, value])) { // 此处TS可自动推断:multiple === true,value为string[]类型 value.forEach(item => console.log(item)) // 无类型报错 }
该方案完全复用校验逻辑,不需要调整现有变量结构,使用时仅需将两个变量放在数组中传入即可,成本极低。
方案2:泛型场景单值断言(适配你的业务代码)
如果你大部分场景只需要收敛value的类型,multiple的取值可以通过逻辑隐含确定,可以直接针对你的泛型场景定义守卫,适配现有PropTypes结构:
type ValueType<M extends boolean> = M extends true ? Array<string> : string; interface PropTypes<M extends boolean> { multiple: M, } // 泛型守卫定义 function isMultiValue<M extends boolean>(multiple: M, value: ValueType<M>): value is string[] { return multiple && Array.isArray(value) } function myFunction<M extends boolean>({ multiple }: PropTypes<M>) { let value: ValueType<M> = /* 你的赋值逻辑 */ '' as any; if (isMultiValue(multiple, value)) { // 此处value自动推断为string[],同时可确定multiple为true value.map(item => item.toUpperCase()) // 无类型报错 } }
可辨识联合报错说明
你之前赋值可辨识联合报错,是因为泛型参数M extends boolean在函数内部没有被收窄,TS 无法将泛型类型和具体的布尔字面量关联,不需要强制使用可辨识联合,上述两种方案即可覆盖所有需求。
内容的提问来源于stack exchange,提问作者Adam Thompson
相关产品推荐
相关产品推荐

