semlinker/awesome-typescript

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

Opened this issue · 13 comments

实现一个 Add 工具类型,用于实现对数值类型对应的数值进行加法运算。具体的使用示例如下所示:

type Add<T, R> = // 你的实现代码

type A0 = Add<5, 5>; // 10
type A1 = Add<8, 20> // 28
type A2 = Add<10, 30>; // 40

请在下面评论你的答案

type Push<T extends any[], V> =  [...T, V];

type CreateTuple<
  T extends number,
  A extends any[] = []
> = A['length'] extends T ? A : CreateTuple<T, Push<A, ''>>

type Add<
  T extends number,
  R extends number
> = [...CreateTuple<T>, ...CreateTuple<R>]['length']

type A0 = Add<5, 5>; // 10
type A1 = Add<8, 20> // 28
type A2 = Add<10, 30>; // 40

没啥难的,就是通过数值,构建对应长度的数组的常规操作

//  构建数组
type GenArr<T extends number, S extends any[] = []> = S['length'] extends T ? S : GenArr<T, [...S, 1]>

type Add<T extends number, R extends number> = [...GenArr<T>, ...GenArr<R>]['length']

type A0 = Add<5, 5>; // 10
type A1 = Add<8, 20> // 28
type A2 = Add<10, 30>; // 40
type Add<
  N extends number,
  M extends number,
  S extends any[] = [],
  Q1 extends any[] = [],
  Q2 extends any[] = [],
  L1 = Q1["length"],
  L2 = Q2["length"],
  L = S["length"],
> = L1 extends N
  ? L2 extends M
    ? L
    : Add<N, M, [...S, 1], Q1, [...Q2, 1]>
  : Add<N, M, [...S, 1], [...Q1, 1], Q2>;

//  测试用例
type S0 = Add<100, 200>; // 300

使用之前所写的类型

type Add<T extends number, R extends number> = Len<
  [...Repeat<" ", T>, ...Repeat<" ", R>]
>;

type A0 = Add<5, 5>; // 10
type A1 = Add<8, 20>; // 28
type A2 = Add<10, 30>; // 40
type Add<T, R, A1 extends any[] = [], A2 extends any[] = [], AT extends any[] = []> = A1["length"] extends T
  ? A2["length"] extends R
    ? AT["length"]
    : Add<T, R, A1, [...A2, ""], [...AT, ""]>
  : Add<T, R, [...A1, ""], A2, [...AT, ""]>

type A0 = Add<5, 5>; // 10
type A1 = Add<8, 20> // 28
type A2 = Add<10, 30>; // 40

思路: 依然是构造数组长度

export default {}

// 实现一个 Add 工具类型,用于实现对数值类型对应的数值进行加法运算。具体的使用示例如下所示:

type Add<T, R, TArr extends any[] = [], RArr extends any[] = []> = (
TArr['length'] extends T ? RArr['length'] extends R ? [...TArr, ...RArr]['length'] : Add<T, R, TArr, [...RArr, 1]> : Add<T, R, [...TArr, 1], RArr>
)

type A0 = Add<5, 5>; // 10
type A1 = Add<8, 18> // 28
type A2 = Add<10, 15>; // 40

type Add<T, R, Arr1 extends any[] = [], Arr2 extends any[] = []> = Arr1['length'] extends T
? Arr2['length'] extends R
? [...Arr1, ...Arr2]['length']
: Add<T, R, Arr1, [...Arr2, '']>
: Add<T, R, [...Arr1, ''], Arr2>

type A0 = Add<5, 5>; // 10
type A1 = Add<8, 20> // 28
type A2 = Add<10, 30>; // 40

type Add<T, R, Arr1 extends any[] = [], Arr2 extends any[] = []> = Arr1['length'] extends T
? Arr2['length'] extends R
? [...Arr1, ...Arr2]['length']
: Add<T, R, Arr1, [...Arr2, '']>
: Add<T, R, [...Arr1, ''], Arr2>

type A0 = Add<5, 5>; // 10
type A1 = Add<8, 20> // 28
type A2 = Add<10, 30>; // 40

type BuildArray<
  T extends number,
  C extends number[] = []
> = C["length"] extends T ? C : BuildArray<T, [...C, number]>;

type Add<T extends number, R extends number> = [
  ...BuildArray<T>,
  ...BuildArray<R>
]["length"];
// 类似前面两题, 需要构建数值对应的数组, 然后返回该数组的长度即可
type NumToArr<T, L extends number = 0, R extends any[] = []> = T extends L ? R : NumToArr<T, R['length'], [...R, '']>

type Add<T, R> = [...NumToArr<T>, ...NumToArr<R>]['length']
dentm commented
type loop<T, U extends any[] = []> = U['length'] extends T ? U : loop<T,[...U, 1]>  

type Add<T extends number, R extends number> = [...loop<T>, ...loop<R>]['length']
  

 // 你的实现代码

 type A0 = Add<5, 5>; // 10
 type A1 = Add<8, 20> // 28
 type A2 = Add<10, 30>; // 40
type BuildArr<T extends number, R extends any[] = []> = R['length'] extends T ? R: BuildArr<T, [...R, 1]>;
type Add<T extends number, R extends number> = [...BuildArr<T>, ...BuildArr<R>]['length'] // 你的实现代码

type A0 = Add<5, 5>; // 10
type A1 = Add<8, 20> // 28
type A2 = Add<10, 30>; // 40
type Add<T, R, A extends any[] = [], B extends any[] = [],> = A['length'] extends T ?
  B['length'] extends R ? [...A, ...B]['length'] : Add<T, R, A, [...B, '']>
  : Add<T, R, [...A, ''], B>

type A0 = Add<5, 5>; // 10
type A1 = Add<8, 20> // 28
type A2 = Add<10, 30>; // 40