模板文字类型 打字稿 重复

Template Literal Types Typescript repeat

提问人:Kousha 提问时间:12/17/2020 更新时间:12/17/2020 访问量:2985

问:

是否可以使用模板文字类型构建重复?例如:

type Hex = 'a' | 'b' | 'c'| ...;
type Id = `${Hex}${Hex}...` // Here I want to say Id is N hex long. 
打字稿

评论

0赞 captain-yossarian from Ukraine 12/17/2020
您到底期望什么类型?请你从字面上添加它吗?因为产生所有对的联合类型${Hex}${Hex}...

答:

9赞 A_blop 12/17/2020 #1

原则上,这可以通过 TS 4.1 中的递归条件类型来实现:

type Decrement = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
type RepeatString<S extends string, N extends number> =
    N extends 1 ? S :
    `${S}${RepeatString<S, Decrement[N]>}`
type T11 = Decrement[5] // 4
type T12 = RepeatString<"foo", 3> // "foofoofoo"
type T13 = RepeatString<Hex, 3> // "aaa" | "aab" | ... | "ccb" | "ccc"

请注意以下限制

请注意,联合类型的跨产品分布可能会迅速升级为非常大且成本高昂的类型。另请注意,工会类型限制为少于 100,000 个成分 [.](我的重点)

例如,对于 being(10 个联合部分),将触发以下错误(排列):Hex2'a' | 'b' | ... | 'i' | 'j'type T14 = RepeatString<Hex2, 5>10*10*10*10*10

表达式生成的联合类型过于复杂,无法表示。(2590)

在这种情况下,需要减少联合部分的数量,例如找到更大的字符串块而不是原子字符。

另类

type RepeatStringAlt<S extends string, N extends number> = RepeatStringAltRec<S, TupleOf<unknown, N>>
type RepeatStringAltRec<S extends string, T extends unknown[]> =
    T["length"] extends 1 ? S : `${S}${RepeatStringAltRec<S, DropFirst<T>>}`
    
type TupleOf<T, N extends number> = N extends N ? number extends N ? T[] : _TupleOf<T, N, []> : never;
type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>;
type DropFirst<T extends readonly unknown[]> = T extends readonly [any?, ...infer U] ? U : [...T];

type T23 = RepeatStringAlt<"foo", 3> // "foofoofoo"

这样就不必再用 手动计算数字范围了。Decrement

实时代码游乐场

评论

0赞 Monday Fatigue 12/30/2022
谢谢。可以按泛型类型进行分布,从而避免了交叉产品问题: stackoverflow.com/a/63401962/4592648