在react中,如何拿到某个组件的props类型
react组件也是一个函数或者class,这里我们讨论为react组件为函数组件。 换而言之,也就是我们如何拿到一个函数参数的类型。 可以通过Parameters
工具类型
typescript
// 例如,我们如何知道子组件的props类型
type Form = Parameters<typeof Form>[0];
type ValidateStatus = Parameters<typeof Form.Item>[0]['validateStatus'];
如何实现Parameters<>
工具类型呢
typescript
type Parameters<T> = T extends (...arg:infer P)=> any ? P :any
typescript
type function = (...arg) => any
//温习一下:函数中的剩余参数...,它只能出现在函数的最后一个参数位置。在函数内部,剩余参数会被自动转换为一个数组,该数组包含了所有剩余的参数。
// ts会将这里的arg推断为any[],注意不是any
infer关键字 infer 是一种特殊的关键字,用于从泛型类型中推断出某个类型,并将其作为类型变量使用。通过 infer,可以在不知道某个类型的具体实现方式的情况下,动态地获取该类型中的某个部。
typescript
// 从函数类型中推断函数返回值类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
function add(a: number, b: number): number {
return a + b;
}
type AddReturnType = ReturnType<typeof add>; // 类型 AddReturnType 推断为 number,因为 add 函数的返回值类型为 number。
//在这个示例中,我们定义了一个类型 ReturnType,用于获取函数的返回值类型。在 ReturnType 中,我们使用了条件类型,根据泛型类型 T 是否可以转换为函数类型来判断是否需要使用 infer R 来推断函数的返回值类型,并将其作为类型变量 R 使用。最后将 R 作为 ReturnType 的返回值类型。
// 从元素类型中推断数组类型
type ArrayElementType<T> = T extends (infer P)[] ? P:never;
const arr1 = [1,2,3];
type Arr1ElementType = ArrayElementType<typeof arr1> // 类型 Arr1ElementType 推断为 number,因为 arr1 的元素类型为 number。
const arr2 = ["hello", "world"];
type Arr2ElementType = ArrayElementType<typeof arr2>;// 类型 Arr2ElementType 推断为 string,因为 arr2 的元素类型为 string。
条件类型 条件类型是一种可以根据泛型类型的属性或类型关系来确定某些类型的类型,是一种比较高级的类型操作符。条件类型通常使用三元表达式的形式来表示,具体语法如下:
typescript
T extends U ? X : Y
//T 和 U 分别是泛型类型和目标类型,X 和 Y 分别是两种备选类型,如果泛型类型 T 可以转换为目标类型 U,则返回类型 X,否则返回类型 Y。
1.判断泛型类型是否为某个类型
typescript
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
2.提取泛型类型的某个属性类型
typescript
interface User {
name: string;
age: number;
address: {
city: string;
street: string;
};
}
type AddressType<T> = T extends { address: infer U } ? U : never;
type Address = AddressType<User>; // { city: string; street: string; }
3.提取泛型类型中满足某个条件的属性类型
typescript
interface User {
name: string;
age: number;
address: {
city: string;
street: string;
};
}
type StringKeys<T> = {
[K in keyof T]: T[K] extends string ? K : never;
}[keyof T];
type StringProps<T> = Pick<T, StringKeys<T>>;
type StringAddress = StringProps<User>["address"]; // { city: string; street: string; }