如何在TypeScript中声明元素值匹配的约束元组?
如何自动生成元素值匹配的元组类型?
我想要创建一种配对类型,仅允许从给定的字符串联合类型中分配值完全匹配的元素。
已实现的基础功能
- 从const断言数组生成字符串联合类型:
const allFoos = ['foo', 'bar', 'baz'] as const; // 生成字符串联合类型 ('foo' | 'bar' | 'baz') type Foo = typeof allFoos[number];
- 创建允许联合类型任意两个元素的元组:
// 允许任意两个Foo类型元素的元组 type Pair = readonly [Foo, Foo]; const good: Pair = ['foo', 'bar']; // 正常赋值 const bad: Pair = ['foo', 'zzz']; // 编译错误(符合预期)
需求:仅允许元素值相同的元组
我需要的是仅允许两个元素值完全一致的元组类型。手动枚举所有可能的变体虽然可行:
type HandWrittenMatchedPair = | readonly ['foo', 'foo'] | readonly ['bar', 'bar'] | readonly ['baz', 'baz']; const good: HandWrittenMatchedPair = ['foo', 'foo']; // 正常赋值 const bad: HandWrittenMatchedPair = ['foo', 'baz']; // 编译错误(符合预期)
但当联合类型元素增多,或是需要定义N元素的同值元组时,手写所有变体完全不现实。因此我希望能自动生成这类类型:
// 如何实现这个自动生成的MatchedPair? type MatchedPair = [???]; // 预期效果 const good: MatchedPair = ['foo', 'foo']; // 正常赋值 const bad: MatchedPair = ['foo', 'bar']; // 触发编译错误
解决方案:可行,利用泛型自动生成
可以通过泛型遍历联合类型的每个成员,为每个成员生成对应同值元组,最终自动组合成联合类型:
type MatchedPair<T extends string = Foo> = { [K in T]: readonly [K, K] }[T]; // 测试效果 const good1: MatchedPair = ['foo', 'foo']; // 正常赋值 const good2: MatchedPair = ['bar', 'bar']; // 正常赋值 const bad1: MatchedPair = ['foo', 'bar']; // 编译错误(符合预期) const bad2: MatchedPair = ['baz', 'foo']; // 编译错误(符合预期)
如果需要支持任意N长度的同值元组,可以进一步扩展泛型:
type SameValueTuple<T, N extends number, R extends T[] = []> = R['length'] extends N ? readonly [...R] : SameValueTuple<T, N, [...R, T]>; // 生成3个元素的同值元组 type MatchedTriple = { [K in Foo]: SameValueTuple<K, 3> }[Foo]; const tripleGood: MatchedTriple = ['foo', 'foo', 'foo']; // 正常赋值 const tripleBad: MatchedTriple = ['foo', 'foo', 'bar']; // 编译错误(符合预期)
内容的提问来源于stack exchange,提问作者jai_
相关产品推荐
相关产品推荐

