如何检查any类型对象是否符合联合类型(MomentInput场景示例)
类型安全处理:将any类型对象适配到第三方库的联合输入类型
问题描述
我从外部库A拿到一个any类型的对象,要传给库B的函数,但该函数要求输入类型为B-Input(比如number | string | somethingCustom这类联合类型),怎么检查这个对象是否兼容?
具体场景:MomentJS的moment()函数要求输入MomentInput类型,但Angular的AbstractControl.value是any类型。我需要一种类型安全的处理方式,确保传入值符合函数预期,否则抛出错误,不想直接禁用Linter的no-unsafe-argument报错。
原代码示例:
someFunction(obj: any): Moment { // 未检查obj是否符合moment()的输入类型 // Linter报no-unsafe-argument错误,禁用检查工具并不理想 return moment(obj) }
解决方案
1. 自定义类型守卫函数
先明确MomentInput的实际类型范围:它包含string | number | Date | Moment | null | undefined,我们可以针对这些类型写一个运行时检查的类型守卫,同时让TypeScript在编译时识别类型兼容性。
function isMomentInput(value: any): value is MomentInput { // 处理null/undefined的情况 if (value == null) { return true; } // 检查字符串、数字这类基本类型 const type = typeof value; if (type === 'string' || type === 'number') { return true; } // 检查Date实例 if (value instanceof Date) { return true; } // 检查Moment实例(利用Moment自带的判断方法) if (typeof moment.isMoment === 'function' && moment.isMoment(value)) { return true; } // 其他情况均不符合 return false; }
2. 在业务函数中加入检查逻辑
修改原来的someFunction,先通过类型守卫验证输入,不符合就抛出错误。这样TypeScript会自动推断此时的obj是MomentInput类型,Linter的no-unsafe-argument报错也会消失。
someFunction(obj: any): Moment { if (!isMomentInput(obj)) { throw new Error(`传入的值不符合MomentInput类型: ${JSON.stringify(obj)}`); } return moment(obj); }
3. 通用联合类型检查思路
如果是其他第三方库的联合输入类型,通用处理步骤如下:
- 先明确目标联合类型包含的所有子类型
- 针对每个子类型编写运行时检查逻辑:基本类型用
typeof,引用类型用instanceof,自定义类型可以检查特定属性或方法 - 封装成类型守卫函数,让TypeScript能在编译时识别类型合法性
内容的提问来源于stack exchange,提问作者fortuneNext
相关产品推荐
相关产品推荐

