TypeScript Type-Exercises-3

    Jan 10, 2024

    Equals

    type Equals<T, U> = T extends U ? (U extends T ? true : false) : false;
    
    type Type1 = { a: number; b: string };
    type Type2 = { a: number; b: string };
    type Type3 = { a: number; c: string };
    
    type Test1 = Equals<Type1, Type2>; // true
    type Test2 = Equals<Type1, Type3>; // false
    

    If

    type If<C extends boolean, T, F> = C extends true ? T : F;
    
    type A = If<true, "a", "b">; // expected to be 'a'
    type B = If<false, "a", "b">; // expected to be 'b'
    

    Includes

    type Includes<T extends any[], U> = {
      [K in T[number]]: true;
    }[U] extends true
      ? true
      : false;
    
    type MyType = Includes<["Kars", "Esidisi", "Wamuu", "Santana"], "Dio">;
    // expected to be `false`
    

    Merge

    type Merge<T> = {
      [P in keyof T]: T[P];
    };
    

    Diff

    type Diff<O, O1> = Merge<
      {
        [P in Exclude<keyof O, keyof O1>]: O[P];
      } & {
        [P in Exclude<keyof O1, keyof O>]: O1[P];
      }
    >;
    

    Ranged Number

    type IsMore<A extends number, B extends number, L extends any[] = []> = A extends L["length"]
      ? false
      : B extends L["length"]
        ? true
        : IsMore<A, B, [...L, any]>;
    type NumRange<Max, Min> = isMore<infer U, Min> extends true ? (isMore<Max, U> extends true ? U : never) : never;
    
    type MyType = NumRange<1000, 9999>;
    // Only number 1000-9999 can be accepted.
    

    Tuple To Union

    type TupleToUnion<T extends any[]> = T[number];
    
    type Arr = ["1", "2", "3"];
    const test: TupleToUnion<Arr>; // expected to be '1' | '2' | '3'
    

    String To Union

    type StringToUnion<T extends string> = T extends `${infer First}${infer Reset}` ? First | StringToUnion<Reset> : never;
    type Test = "123";
    type Result = StringToUnion<Test>; // expected to be "1" | "2" | "3"
    

    Length of String

    type LengthOfString<S extends string, T extends any[] = []> = S extends `${infer L}${infer R}`
      ? LengthOfString<R, [...T, L]>
      : T["length"];
    
    type MyType = LengthOfString<"hello">; // 5