Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs React和Typescript:如何扩展通用组件道具?_Reactjs_Typescript_Generics_React Component - Fatal编程技术网

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
只包含三个键,其中一个键aka
a
已用尽。在
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

希望这能回答您的问题并解决您的问题