[英]Typescript infer rest type of generic object type
我正在为类似反应的功能组件编写部分 function。 它接受单个参数props
,然后填充 props 的特定键。 例如,部分 function foo
将 prop bar
的值填充到新组件中。
function foo<T extends {bar: number}>(functionalComponent: (props: T) => JSX.Element) {
return (props: Omit<T, 'bar'>) => {
return functionalComponent({...props, bar: 3});
}
}
然而,typescript 编译器抱怨:
'省略<T, "bar"> & { bar: number; }' 可分配给类型 'T' 的约束,但 'T' 可以用约束的不同子类型实例化 '{ bar: number; }'
这个问题与这个非常相似,它使用infer
作为参数列表。 但是,我没有找到 object 版本,而是找到了这个 github issue ,它建议使用Omit
。 但是, Omit
不适用于泛型。
一个小例子来说明这个问题:
function func<T extends {foo: number}>(param: Omit<T, 'foo'>): T {
return {...param, foo: 3};
}
'省略<T, "foo"> & { foo: number; }' 可分配给类型 'T' 的约束,但 'T' 可以用约束的不同子类型实例化 '{ foo: number; }'
我还检查了解释此错误的答案,但仍然无法理解。
如何使部分 function 类型签名起作用?
Typescript 无法理解Omit
会发生什么,只要它仍然有一个未解析的泛型类型参数。 我们可以做些什么来让它进行类型检查,就是在functionalComponent
的props
中添加一个带有Omit<T, 'bar'> & {bar: number}
的联合。 虽然这看起来与T
相同,但它的包含将使 typescript 将包装的组件道具分配给功能组件道具。 当T
被解析时, T
和Omit<T, 'bar'> & {bar: number}
将解析为相同的有效类型,因此它对调用站点应该没有影响:
type BaseProps ={bar: number}
function foo<T extends BaseProps>(functionalComponent: (props:
| T
| Omit<T, 'bar'> & BaseProps ) => JSX.Element) {
return (props: Omit<T, 'bar'>) => {
return functionalComponent({...props, bar: 3});
}
}
我找到了一个蛮力解决方法:使用as
关键字。 不确定是否有更好的解决方案,所以我将其悬而未决。
function func<T extends {foo: number}>(param: Omit<T, 'foo'>): T {
return {...param, foo: 3} as T;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.