Reactjs React和Typescript:如何扩展通用组件道具?
想象一个灵活的组件,它接受一个Reactjs React和Typescript:如何扩展通用组件道具?,reactjs,typescript,generics,react-component,Reactjs,Typescript,Generics,React Component,想象一个灵活的组件,它接受一个React.ComponentType及其道具并呈现: 类型道具={ 组件:React.ComponentType; 组成部分:C; 其他属性:字符串; }; 常量MyComponent=(道具:道具)=>{ 返回React.createElement(props.component,props.componentProps); }; 我是否可以让MyComponent直接接收动态的道具,例如这样(不工作): 类型道具={ 组件:React.ComponentTy
React.ComponentType
及其道具
并呈现:
类型道具={
组件:React.ComponentType;
组成部分:C;
其他属性:字符串;
};
常量MyComponent=(道具:道具)=>{
返回React.createElement(props.component,props.componentProps);
};
我是否可以让MyComponent直接接收动态的道具,例如这样(不工作):
类型道具={
组件:React.ComponentType;
其他属性:字符串;
};
常量MyComponent=(道具:道具和C)=>{
const{otherProp,component,…componentProps}=props;
返回React.createElement(component,componentProps);
};
错误:
Error:(11, 41) TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type 'Pick<Props<C> & C, Exclude<keyof C, "component" | "otherProp">>' is not assignable to parameter of type 'Attributes & C'.
Type 'Pick<Props<C> & C, Exclude<keyof C, "component" | "otherProp">>' is not assignable to type 'C'.
'Pick<Props<C> & C, Exclude<keyof C, "component" | "otherProp">>' is assignable to the constraint of type 'C', but 'C' could be instantiated with a different subtype of constraint '{}'.
错误:(11,41)TS2769:没有与此调用匹配的重载。
上一次重载导致以下错误。
“Pick”类型的参数不能分配给“Attributes&C”类型的参数。
类型“Pick”不可分配给类型“C”。
“Pick”可分配给“C”类型的约束,但“C”可以用约束“{}”的不同子类型实例化。
在这里,我们需要了解一些实用程序类型以及在TS中如何进行解构
类型Obj={
[键:字符串]:任何
}
接口I1{
a:号码
b:号码
c:号码
}
常数i1:i1={
答:1,,
b:1,
c:1,
}
设{a,…rest}=i1
接口对象{
[键:字符串]:任何
}
常数i2:Obj&I1={
答:1,,
b:1,
c:1,
d:1,
e:1,
}
设{a:a1,b,c,…rest2}=i2
函数func(参数:I1&T){
常数{a,b,c,…rest}=param
}
在上面的代码中,rest
的推断类型将是{b:number,c:number}
,因为对象i1
只包含三个键,其中一个键akaa
已用尽。在rest2
的情况下,TS仍然可以推断出Obj
的类型,因为接口I1
中的键已用完。我所说的耗尽是指它们不是使用rest操作符捕获的
但在函数的情况下,TS不能进行这种类型的推理。我不知道TS为什么做不到。这可能是由于泛型的限制
对于函数,函数内部的rest
类型是Pick
<代码>排除
从泛型类型T
中排除键a
、b
和c
。选中排除。然后,Pick
使用Exclude
返回的键从I1&T
创建一个新类型。由于T
可以是任何类型,因此即使T被约束为Obj
,TS也无法确定排除后的关键帧,因此无法确定拾取的关键帧,也无法确定新创建的类型。这就是为什么函数中的类型变量rest
保持为Pick
请注意,Pick
返回的类型是Obj
现在来看这个问题,componentProps
也会出现同样的情况。推断出的类型将是Pick
。TS将无法缩小范围。查看React.createElement的签名
函数createElement(
类型:ComponentType
|字符串,
道具?:属性&P |空,
…子级:ReactNode[]):ReactElement
并称之为
React.createElement(组件,组件Props)
签名中p
的推断类型将是第一个参数中代码中的C
,即component
,因为它具有类型React.ComponentType
。第二个参数应该是undefined
或null
或C
(从现在起忽略Attributes
)。但是componentProps
的类型是Pick
,它肯定可以分配给{}
,但不能分配给C
,因为它是{}
的子类型,而不是C
C
也是{}
的一个子类型,但拾取类型和C
可能兼容,也可能不兼容(这与-存在一个类a相同;B和C派生a,B和C的对象可分配给a,但B的对象不可归属于C)。这就是错误的原因
'Pick<Props<C> & C, Exclude<keyof C, "component" | "otherProp">>' is assignable to the constraint of type 'C', but 'C' could be instantiated with a different subtype of constraint '{}'.
“Pick”可分配给“C”类型的约束,但“C”可以用约束“{}”的不同子类型实例化。
由于我们比TS编译器更智能,我们知道它们是兼容的,但TS不兼容。所以让TS相信我们做的是正确的,我们可以这样做一个类型断言
类型道具={
组件:React.ComponentType;
其他属性:字符串;
};
常量MyComponent=(道具:道具和C)=>{
const{otherProp,component,…componentProps}=props;
返回React.createElement(component,componentProps与C一样未知);
// ------------------------------------------------^^^^^^^^
};
这绝对是一个正确的类型断言,因为我们知道componentProps
的类型将是C
希望这能回答您的问题并解决您的问题