繁体   English   中英

Typescript 推断 rest 泛型 object 类型

[英]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会发生什么,只要它仍然有一个未解析的泛型类型参数。 我们可以做些什么来让它进行类型检查,就是在functionalComponentprops中添加一个带有Omit<T, 'bar'> & {bar: number}的联合。 虽然这看起来与T相同,但它的包含将使 typescript 将包装的组件道具分配给功能组件道具。 T被解析时, TOmit<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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM