跳至主要內容

BFE-TS TypeScript类型体操练习 Easy 21-30

YihuiTypeScript大约 3 分钟

BFE-TS TypeScript类型体操练习 Easy 21-30

常用工具类型

  1. 实现 ReplaceAll<S, F, T>

    正如String.prototype.replaceAll(),请实现ReplaceAll<S, F, T>

    type A = ReplaceAll<'aba', 'b', ''> // 'aa'
    type B = ReplaceAll<'ababbab', 'b', ''> // 'aaa'
    

    答案:

    1、前、中、后分别取一下infer。

    2、 判断F不为空

    type ReplaceAll<
      S extends string,
      F extends string,
      T extends string
      > = F extends '' ? S : (S extends `${F}${infer R}` ? `${T}${ReplaceAll<R, F, T>}` :
        (S extends `${infer A}${F}${infer B}` ? `${A}${T}${ReplaceAll<B, F, T>}` :
          S extends `${infer A}${F}` ? `${ReplaceAll<A, F, T>}${T}` : S
        ));
    
  2. 实现 Trim<T> 正如String.prototype.trim(),请实现Trim<T>

    type A = Trim<'    BFE.dev'> // 'BFE'
    type B = Trim<' BFE. dev  '> // 'BFE. dev'
    type C = Trim<'  BFE .   dev  '> // 'BFE .   dev'
    

    答案:

    type Trim<T extends string> = T extends ` ${infer R}` 
      ? Trim<R> 
      : T extends `${infer L} `
        ? Trim<L>
        : T
    
  3. 实现 Equal<A, B> 检测俩类型是完全相同的

    Equal<any, any> // true
    Equal<any, 1> // false
    Equal<never, never> // true
    Equal<'BFE', 'BFE'> // true
    Equal<'BFE', string> // false
    Equal<1 | 2, 2 | 1> // true
    Equal<{a : number}, {a: number}> // true
    

    答案:

    type Equal<T, K> = [T] extends [K] ? [K] extends [T] ? (keyof T extends keyof K ? keyof K extends keyof T ? true : false : false) : false : false;
    
    // or
    
    type Equals<X, Y> =
      (<T>() => T extends X ? 1 : 2) extends
      (<T>() => T extends Y ? 1 : 2) ? true : false;
    
  4. 实现 FindIndex<T, E> 正如Array.prototype.findIndex(), 请实现FindIndex<T, E>

    type A = [any, never, 1, '2', true]
    type B = FindIndex<A, 1> // 2
    type C = FindIndex<A, 3> // never
    

    答案:

    type Equals<X, Y> =
      (<T>() => T extends X ? 1 : 2) extends
      (<T>() => T extends Y ? 1 : 2) ? true : false;
    
    type FindIndex<T extends any[], E> =
      T extends [...infer Rest, infer EE]
      ? Equals<EE, E> extends true
        ? FindIndex<Rest, E> extends never
          ? Rest["length"]
          : FindIndex<Rest, E>
        : FindIndex<Rest, E>
      : never;
    
  5. 实现 UnionToIntersection<T> 请实现UnionToIntersection<T>用以从Union(或)得到Intersection(与/交)。

    type A = UnionToIntersection<{a: string} | {b: string} | {c: string}> 
    // {a: string} & {b: string} & {c: string}
    

    答案:

    type UnionToIntersection<U> = 
      (
        U extends any 
          ? (x: U) => void 
          : never
      ) extends ((x: infer I) => void) 
          ? I 
          : never
    

    关于这是如何工作的可以参见typescript - Transform union type to intersection type - Stack Overflowopen in new window

  6. 实现 ToNumber<T> 请实现ToNumber<T>用来转换字符串为整数。

    type A = ToNumber<'1'> // 1
    type B = ToNumber<'40'> // 40
    type C = ToNumber<'0'> // 0
    

    答案:

    type ToNumber<T extends string, U extends number[] = []> =
      `${U['length']}` extends T
        ? U['length']
        : ToNumber<T, [...U, 1]>
    
  7. 实现 Add<A, B> 实现Add<A, B>计算正整数之和。

    type A = Add<1, 2> // 3
    type B = Add<0, 0> // 0
    

    答案:

    type Tuple<T extends number, U extends any[] = []> = U['length'] extends T ? U : Tuple<T, [...U, any]>
    
    type Add<A extends number, B extends number> = [...Tuple<A>, ...Tuple<B>]['length']
    
  8. 实现 SmallerThan<A, B>

    type A = SmallerThan<0, 1> // true
    type B = SmallerThan<1, 0> // false
    type C = SmallerThan<10, 9> // false
    

    答案:

    type SmallerThan<
      A extends number,
      B extends number,
      S extends number[] = []
    > = S['length'] extends B
      ? false
      : S['length'] extends A
      ? true
      : SmallerThan<A, B, [A, ...S]>
    
  9. 实现 LargerThan<A, B>

    type A = LargerThan<0, 1> // false
    type B = LargerThan<1, 0> // true
    type C = LargerThan<10, 9> // true
    

    答案:

    type LargerThan<A extends number, B extends number, S extends any[] = []> =
      S['length'] extends A
      ? false
      : S['length'] extends B
      ? true
      : LargerThan<A, B, [...S, any]>
    

    继续推进数组,直到它到达其中一个数字,到达的第一个数字就是较小的

  10. 实现 Filter<T, A> 实现Filter<T, A>,返回T中能够assign给A的type所组成的新tuple。

    type A = Filter<[1,'BFE', 2, true, 'dev'], number> // [1, 2]
    type B = Filter<[1,'BFE', 2, true, 'dev'], string> // ['BFE', 'dev']
    type C = Filter<[1,'BFE', 2, any, 'dev'], string> // ['BFE', any, 'dev']
    

    答案:

    type Filter<T extends any[], A, R extends A[] = []> = 
      T extends [infer F, ...infer O] 
        ? [F] extends [A]
          ? Filter<O, A, [...R, F]>
          : Filter<O, A, R>
        : R