能否获取继承数组类型的泛型参数的值?附类型守卫实现场景
问题解答:获取泛型数组类型的有效值并实现类型守卫
你原代码的核心问题是:泛型参数C是类型层面的标识,在运行时根本不存在,所以直接写new Set(C)会报错——C不是一个可访问的运行时变量。
要实现「检查值是否在指定数组中」的类型守卫,必须让函数同时拿到运行时的数组值和类型层面的数组元素类型,正确的实现方式如下:
方式一:返回可复用的类型守卫函数
这种方式适合需要多次复用同一组允许值的场景:
function createIsInList<C extends string>(allowedValues: readonly C[]) { const valueSet = new Set(allowedValues); return (attribute: string): attribute is C => valueSet.has(attribute as C); } // 使用示例 const allowedSizes = ['small', 'medium', 'large'] as const; const isSize = createIsInList(allowedSizes); const input = 'medium'; if (isSize(input)) { // 此处input的类型会被推断为 'small' | 'medium' | 'large' console.log(input); }
方式二:单次检查的函数
如果只需要单次检查,也可以把数组和待检查值放在同一个函数里:
function isInList<C extends string>(attribute: string, allowedValues: readonly C[]): attribute is C { const valueSet = new Set(allowedValues); return valueSet.has(attribute as C); } // 使用示例 const input = 'red'; if (isInList(input, ['red', 'green', 'blue'] as const)) { // 此处input的类型会被推断为 'red' | 'green' | 'blue' }
关键说明
- 用
readonly C[]或C[]作为参数,TS会自动从数组元素推导泛型C的类型;加上as const可以让TS推导更精确的字面量类型(比如'red'而不是string)。 - 运行时通过传入的数组创建
Set来做快速查找,同时类型层面通过泛型约束和类型守卫,让TS能正确推断检查后的值类型。
内容的提问来源于stack exchange,提问作者STh
相关产品推荐
相关产品推荐

