awesome-typescript
awesome-typescript copied to clipboard
「重学TS 2.0 」TS 练习题第三十二题
实现一个 RepeatString
工具类型,用于根据类型变量 C
的值,重复 T
类型并以字符串的形式返回新的类型。具体的使用示例如下所示:
type RepeatString<
T extends string,
C extends number,
> = // 你的实现代码
type S0 = RepeatString<"a", 0>; // ''
type S1 = RepeatString<"a", 2>; // 'aa'
type S2 = RepeatString<"ab", 3>; // 'ababab'
请在下面评论你的答案
type Repeat<T, C extends number, A extends any[] = []> = A["length"] extends C
? A
: Repeat<T, C, [...A, T]>;
type Join<T extends string[], splitor extends string = ""> = T extends [infer F, ...infer R]
? R extends string[]
? F extends string
? `${F}${splitor}${Join<R, splitor>}`
: ""
: F
: "";
type RepeatString<T extends string, C extends number> = Join<Repeat<T, C>, "">;
type S0 = RepeatString<"a", 0>; // ''
type S1 = RepeatString<"a", 2>; // 'aa'
type S2 = RepeatString<"ab", 3>; // 'ababab'
type Push<T extends any[], V> = [...T, V];
type RepeatString<
T extends string,
C extends number,
R extends string = '',
A extends any[] = [],
> = A['length'] extends C ? R: (RepeatString<T, C, `${R}${T}`, Push<A, T>>)
type S01 = RepeatString<"a", 0>; // ''
type S11 = RepeatString<"a", 2>; // 'aa'
type S21 = RepeatString<"ab", 3>; // 'ababab'
type S22 = RepeatString<"abc", 3>; // 'abcabcabc'
用模板字符串进行递归就行了
type RepeatString<
T extends string,
C extends number,
S extends any[] = [], // 用于判断是否递归完毕
U extends string = '' // 用于累加记录已遍历过的字符串
> = S['length'] extends C ? U : RepeatString<T, C, [...S, 1], `${U}${T}`>
直接使用第九题的JoinStrArray操作Repeat后的元组
type RepeatString<T extends string, C extends number> = JoinStrArray<
Repeat<T, C>,
""
>;
type S02 = RepeatString<"a", 0>; // ''
type S12 = RepeatString<"a", 2>; // 'aa'
type S22 = RepeatString<"ab", 3>; // 'ababab'
type RepeatString<T extends string, C extends number, A extends any[] = [], R extends string = ""> = A["length"] extends C
? R
: RepeatString<T, C, [...A, ''], `${R}${T}`;
type S0 = RepeatString<"a", 0>; // ''
type S1 = RepeatString<"a", 2>; // 'aa'
type S2 = RepeatString<"ab", 3>; // 'ababab'
思路: 数字的比较只能利用 数组的 lenght属性来实现,字符串的 length属性在tsc阶段无法获取到真实长度,只能得到number类型。
type _RepeatString<
T extends string,
C extends number,
S extends string,
Count extends string[]
> = Count["length"] extends C
? S
: _RepeatString<T, C, `${S}${T}`, [...Count, T]>;
type RepeatString<T extends string, C extends number> = _RepeatString<
T,
C,
"",
[]
>;
// 将RepeatString拆分成两步: 1. 将其转变成目标数组 2. 将数组拼接成为字符串
// 1. 通过RepeatStr将字符串和数量转变成为数组
// 如: <'ab', 2> => ['ab', 'ab']
type RepeatStr<S extends string, N extends number, R extends string[] = []> = R['length'] extends N ? R : RepeatStr<S, N, [...R, S]>
// 2. 创建一个Join帮助类型, 将重复的数组变成字符串
// 如: ['ab', 'ab'] => 'abab'
type Join<T extends string[]> = T extends [f: infer F, ...r: infer R] ? R extends string[] ? F extends string ? `${F}${Join<R>}` : '' : '' : ''
// 3. 组合上面的两个类型即可
type RepeatString<
T extends string,
C extends number,
> = Join<RepeatStr<T, C>>
type RepeatString<T extends string, C extends number, S extends string = '', R extends T[] = []> = R['length'] extends C
? S
: RepeatString<T, C, `${S}${T}`, [...R, T]>; // 你的实现代码
type S0 = RepeatString<'a', 0>; // ''
type S1 = RepeatString<'a', 2>; // 'aa'
type S2 = RepeatString<'ab', 3>; // 'ababab'
type RepeatString<
T extends string,
C extends number,
A extends any[] = []
> = A['length'] extends C ? '' : `${T}${RepeatString<T, C, [...A, T]>}`
type S0 = RepeatString<"a", 0>; // ''
type S1 = RepeatString<"a", 2>; // 'aa'
type S2 = RepeatString<"ab", 3>; // 'ababab'