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