如何在TypeScript中使用type predicate过滤联合类型?
解决方法
问题根源在于TypeScript对Array.filter()的类型推断逻辑:默认情况下,filter()返回的数组类型会和原数组保持一致,不会自动根据过滤逻辑收窄元素类型。要让TypeScript识别过滤后的元素类型,必须给filter()传入带类型谓词的回调函数,而非用逻辑非包裹已有的类型谓词函数。
方法1:定义正向类型谓词函数
直接定义一个判断元素是否为Fruit的类型谓词函数,传给filter():
function isFruit(item: Fruit | Vegetable): item is Fruit { return "color" in item; } const tastyStuff = healthyStuff .filter(isFruit) .map(item => item.color); // 类型自动收窄为Fruit[],无报错
方法2:在filter回调中直接使用类型谓词
如果不想额外定义函数,可以在filter()的回调里直接声明类型谓词:
const tastyStuff = healthyStuff .filter((item): item is Fruit => !("taste" in item)) .map(item => item.color); // 同样正常工作
为什么for循环能正常运行?
在for循环的if分支中,TypeScript会通过类型守卫自动收窄item的类型,当你把符合条件的item推入数组时,数组的类型会被推断为Fruit[]。但Array.filter()的类型系统无法自动关联!isVegetable(item)对应的类型,必须显式告知TypeScript过滤后的元素具体类型。
内容的提问来源于stack exchange,提问作者Ham Vocke
相关产品推荐
相关产品推荐

