Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

The first question

AppendArgs defines a tool type, which is a function type, and adds an argument of the specified type, named x, as the first argument of the new function type, as shown in the following example

type Fn = (a: number, b: Type FinalFn = AppendArgument<Fn, Boolean > // (x: Boolean, A:) number, b: string) => numberCopy the code

答 案 :

  1. Parameters gets the type of the function’s argument.
  2. ReturnType (gets the return value type of the function).
  3. The use of infer

Answer key 1

Use Parameters and ReturnType, which are explained below if you don’t know.

type AppendArgument<F extends (... args: any) => any, A> = (x: A, ... args: Parameters<F>) => ReturnType<F> type Fn = (a: number, b: string) => number type FinalF = AppendArgument<Fn, boolean> // (x: boolean, a: number, b: string) => numberCopy the code

First define the original Fn and our newly defined parameter A, then use Parameters to take out the original parameter type, assign the value to the original parameter, and finally use RetrnType to return the result type.

Knowledge supplement

Parameters

declare function f1(arg: { a: number; b: string }): void;
 
type T0 = Parameters<() => string>;
type T0 = []
​
type T1 = Parameters<(s: string) => void>;
type T1 = [s: string]
​
type T2 = Parameters<<T>(arg: T) => T>;
type T2 = [arg: unknown]
​
type T3 = Parameters<typeof f1>;
type T3 = [arg: {
    a: number;
    b: string;
}]
Copy the code

As you can see from the above example, Paramters take a function argument or a typeof Fn, which returns the parameter typeof the function.

ReturnType

declare function f1(): { a: number; b: string };
 
type T0 = ReturnType<() => string>;
     
type T0 = string
type T1 = ReturnType<(s: string) => void>;
     
type T1 = void
type T2 = ReturnType<<T>() => T>;
     
type T2 = unknown
type T3 = ReturnType<<T extends U, U extends number[]>() => T>;
     
type T3 = number[]
type T4 = ReturnType<typeof f1>;
     
type T4 = {
    a: number;
    b: string;
}
Copy the code

ReturnType also takes a Fn and constructs a Type Type consisting of the ReturnType of function.

The second question

Define a NativeFlat tool type that supports flat (flattening) of array types. The specific usage example is as follows:

Type NaiveFlat<T extends any[]> = your implementation code // Test case: Type NaiveResult = NaiveFlat < [[' a '], [' b ', 'c'], [' d ']] > / / NaiveResult results: "a" | "b" | | "c" "d"Copy the code

After completing the NaiveFlat utility type, we continue to implement the DeepFlat utility type to support multi-dimensional array types:

Type DeepFlat extends < T any [] > = unknown / / / / your implementation code test cases type Deep = [[' a '], [' b ', 'c'], [[' d ']], [[[[' e ']]]]]. type DeepTestResult = DeepFlat<Deep> // DeepTestResult: "a" | "b" | "c" | "d" | "e"Copy the code

The content of this question

To flatten an array, typeof ArrayInstance[number] gets the corresponding type from the array value

Answer key NativeFlat

type NaiveFlat<T extends any[]> = {
    [P in keyof T ] : T[P] extends any[] ? T[P][number] : T[P]
}[number]
//NaiveResult = ["a", "b" | "c", "d"][number]
type NaiveResult = NaiveFlat<[['a'], ['b', 'c'], ['d']]>
// NaiveResult: "a" | "b" | "c" | "d" | "e"
Copy the code

Subject train of thought is not complicated, first of all get each item, and then decide whether this is an array, if it is [number] used this approach will he converted into joint types, the final returns an array of one yuan, our goal is to return the joint type, so you also need to use a [number] will be the result of a yuan array again converted into joint type

Answer key DeepFlat

type DeepFlat<T extends any[]> = {
    [P in keyof T ] : T[P] extends any[] ? DeepFlat<T[P]>: T[P]
}[number]
type DeepFlatResult = DeepFlat<[['a'], ['b', 'c'], [['d']], [[[['e']]]]]>
Copy the code

This problem is actually a derivative of the above problem, mainly is the use of recursion to achieve multidimensional array expansion