Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
semlinker opened this issue Sep 22, 2021 · 9 comments
Open

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

semlinker opened this issue Sep 22, 2021 · 9 comments

Comments

@semlinker
Copy link
Owner

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

请在下面评论你的答案

@zhaoxiongfei
Copy link

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'

@douhao1988
Copy link

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'

@xiaoYuanDun
Copy link

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

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

@sunboyZgz
Copy link

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

@zhaoxiongfei
Copy link

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

@zjxxxxxxxxx
Copy link

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

@ChangerHe
Copy link

ChangerHe commented May 29, 2022

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

@liziqiang
Copy link

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'

@dolphin0618
Copy link

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'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants