awesome-typescript icon indicating copy to clipboard operation
awesome-typescript copied to clipboard

「重学TS 2.0 」TS 练习题第三十二题

Open semlinker opened this issue 2 years ago • 9 comments

实现一个 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'

请在下面评论你的答案

semlinker avatar Sep 22 '21 13:09 semlinker

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'

zhaoxiongfei avatar Sep 22 '21 15:09 zhaoxiongfei

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'

douhao1988 avatar Sep 22 '21 15:09 douhao1988

用模板字符串进行递归就行了

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}`>

xiaoYuanDun avatar Sep 23 '21 07:09 xiaoYuanDun

直接使用第九题的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'

sunboyZgz avatar Sep 23 '21 11:09 sunboyZgz

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类型。

zhaoxiongfei avatar Oct 03 '21 05:10 zhaoxiongfei

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,
  "",
  []
>;

zjxxxxxxxxx avatar Mar 24 '22 03:03 zjxxxxxxxxx

// 将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>>

ChangerHe avatar May 29 '22 03:05 ChangerHe

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'

liziqiang avatar Jul 15 '22 03:07 liziqiang

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'

dolphin0618 avatar Aug 19 '22 08:08 dolphin0618