如何为TypeScript中过滤后的filteredList定义类型?
TypeScript中filteredList的类型定义问题
先看这段代码:
const list = ['rabbits', 'raccoons', 'reindeer', 'red pandas'] as const const filteredList = list.filter(e => e.includes('re'))
你的疑问解答
你提到的(typeof list[number])[]这个类型定义是正确的,但它属于精度较宽泛的联合类型数组,下面详细解释:
1. 为什么这个类型是合理的
list经过as const断言后是只读元组,typeof list[number]得到的是联合类型:'rabbits' | 'raccoons' | 'reindeer' | 'red pandas'。(typeof list[number])[]表示由该联合类型元素组成的数组——TypeScript无法通过filter的回调自动推断出更精确的类型,因为e.includes('re')在类型层面无法被识别为“仅保留包含're'的元素”,它只能确定过滤后的元素是原数组元素的子集,无法自动缩小到'reindeer' | 'red pandas'。
2. 如何获得更精确的类型
如果希望filteredList的类型精确到仅包含符合条件的元素,可以用以下两种方式:
方式一:手动定义子集类型
const list = ['rabbits', 'raccoons', 'reindeer', 'red pandas'] as const; type ListElement = typeof list[number]; // 用Extract提取包含're'的元素类型,或者直接写死'reindeer' | 'red pandas' type ReElement = Extract<ListElement, `${string}re${string}`>; const filteredList = list.filter(e => e.includes('re')) as ReElement[];
方式二:使用类型守卫函数
const list = ['rabbits', 'raccoons', 'reindeer', 'red pandas'] as const; type ListElement = typeof list[number]; // 定义类型守卫,让TypeScript识别回调的过滤逻辑 function isReElement(e: ListElement): e is Extract<ListElement, `${string}re${string}`> { return e.includes('re'); } const filteredList = list.filter(isReElement); // 此时filteredList会被自动推断为('reindeer' | 'red pandas')[]
3. 关于“重复元素”的误解
(typeof list[number])[]并没有强制数组元素必须重复,它只是表示数组中的每个元素都属于原数组的元素类型,不管是重复还是不重复的组合都符合这个类型。这是联合类型数组的正常特性,并不代表这个类型定义错误,只是它的精度不够高而已。
内容的提问来源于stack exchange,提问作者Ooker
相关产品推荐
相关产品推荐

