如何构建包含指定字符串字面量的TypeScript泛型类型
实现无需额外数组参数的
ArrayContainingLiteral泛型类型 优化后的简洁实现
type ArrayContainingLiteral<Literal extends string> = // 字面量位于数组首位 [Literal, ...string[]] | // 字面量位于数组末位 [...string[], Literal] | // 字面量位于数组中间任意位置 [...string[], Literal, ...string[]];
原理说明
这个实现利用了TypeScript的可变元组类型(TypeScript 4.0+支持),通过三种元组模板覆盖了指定字面量在数组中的所有可能位置:
[Literal, ...string[]]:字面量作为第一个元素,后面跟任意数量的字符串[...string[], Literal]:任意数量的字符串后面跟字面量作为最后一个元素[...string[], Literal, ...string[]]:字面量位于数组中间,前后都有任意数量的字符串
当你给变量赋值数组字面量时,TypeScript会自动将数组推断为元组类型,并检查是否匹配上述三种模板之一:匹配则类型合法,不匹配则触发类型错误。
验证示例
// 'a'位于首位 const x1: ArrayContainingLiteral<'a'> = ['a', 'b', 'c']; // ✅ 类型匹配 // 'a'位于末位 const x2: ArrayContainingLiteral<'a'> = ['b', 'a']; // ✅ 类型匹配 // 'a'位于元素中间 const x3: ArrayContainingLiteral<'a'> = ['b', 'a', 'c', 'd']; // ✅ 类型匹配 // 数组中无'a' const x4: ArrayContainingLiteral<'a'> = ['b', 'c']; // ❌ 类型不匹配(无'a') // 数组为空(无'a') const x5: ArrayContainingLiteral<'a'> = []; // ❌ 类型不匹配(空数组)
补充说明
- 该实现仅针对数组字面量或被推断为元组类型的数组生效,因为宽泛的
string[]类型无法确定具体包含的元素,会被类型检查拒绝 - 如果需要支持包含其他类型元素的数组,只需将模板中的
string替换为你需要的基础类型(比如unknown)
内容的提问来源于stack exchange,提问作者Juraj Zovinec
相关产品推荐
相关产品推荐

