reactjs 类型脚本推断泛型对象类型的剩余类型

xqkwcwgp  于 2023-01-08  发布在  React
关注(0)|答案(2)|浏览(133)

我正在为类React函数组件编写一个partial函数,它接受一个参数props,然后填充属性的一个特定键。例如,partial函数foo将属性bar的值填充到新组件中。

function foo<T extends {bar: number}>(functionalComponent: (props: T) => JSX.Element) {
  return (props: Omit<T, 'bar'>) => {
    return functionalComponent({...props, bar: 3});
  }
}

然而,打字脚本编译器抱怨:
'省略〈T,"小节"〉& {小节:number ;}"可赋给类型" T "的约束,但" T "可以用约束" {bar:数字;}'
这个问题与this one非常相似,this one使用infer作为参数列表,但是,我没有找到对象版本,相反,我发现了这个github问题,建议使用Omit,但是,Omit不适用于泛型。
举个小例子来说明这个问题:

function func<T extends {foo: number}>(param: Omit<T, 'foo'>): T {
  return {...param, foo: 3};
}

'省略〈T,"foo"〉和{foo:number ;}"可赋给类型" T "的约束,但" T "可以用约束" {foo:数字;}'
我还检查了an answer that explains this error,但仍然无法获得要点。
如何使部分函数类型签名工作?

uajslkp6

uajslkp61#

只要Omit中仍然有一个未解析的泛型类型参数,Typescript就无法跟踪Omit将发生的情况。我们可以做的是将Omit<T, 'bar'> & {bar: number}添加到functionalComponentprops中。虽然这看起来与T相同,它的包含会让typescript将 Package 的组件属性分配给功能组件属性。当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});
  }
}

Playground链接

hsgswve4

hsgswve42#

我找到了一个蛮力解决方案:使用as关键字。不确定是否存在更好的解决方案,所以我将保留它未解决。

function func<T extends {foo: number}>(param: Omit<T, 'foo'>): T {
  return {...param, foo: 3} as T;
}

相关问题