如何为as const标记的数组生成的联合类型编写type guard类型守卫
问题原因
你遇到的TS报错是因为用as const声明的items是只读的字面量数组,元素类型为'a' | 'b' | 'c',而TS内置的Array.includes方法要求入参必须是数组元素类型的子类型,你传入的是宽泛的string类型,类型不匹配就触发了2345错误。
解决方案
1. 针对当前场景快速修正
只需要对items做一次安全的类型断言,让它允许接收string类型的入参即可,因为我们本身就是要做合法性校验,这里的断言不会引入安全问题:
const items = ['a', 'b', 'c'] as const; type itemType = typeof items[number]; const isItemType = (item: string): item is itemType => { return (items as readonly string[]).includes(item); }
这里用readonly string[]做断言是因为as const生成的数组默认是只读类型,和实际类型匹配度更高。
2. 通用封装方案(推荐)
可以封装一个通用的类型守卫生成函数,后续所有用as const声明的字面量数组都可以复用这个逻辑,不需要重复写校验代码:
// 通用类型守卫工厂函数 function createLiteralTypeGuard<T extends string | number | boolean>(literalArr: readonly T[]) { return (target: unknown): target is T => { return literalArr.includes(target as T); }; } // 实际使用 const items = ['a', 'b', 'c'] as const; type itemType = typeof items[number]; // 一行生成对应的类型守卫 const isItemType = createLiteralTypeGuard(items);
内容的提问来源于stack exchange,提问作者Georgi Naumov
相关产品推荐
相关产品推荐

