我有以下代码:

type XType<T> = {
  x: T;
};
function extractTypes<Props, T>(Component: React.FC<Props & XType<T>>) {
  return (props: Props, value: T) => {
    Component({ ...props, x: value });
  };
}


const CompA: React.FC<{ a: string } & XType<string>> = () => <div>HELLO</div>;
const CompB: React.FC<{ b: string } & XType<number>> = () => <div>WORLD</div>;


extractTypes<{ a: string }, string>(CompA)({ a: 'A' }, 'X'); // OK
extractTypes<{ b: string }, number>(CompB)({ b: 'B' }, 1);   // OK

extractTypes(CompA)({ a: 'A' }, 'X');                        // Compile error
extractTypes(CompB)({ b: 'B' }, 1);                          // Compile error

CompACompB预期ab属性以及XType中的所有属性.

倒数第三行和倒数第四行编译正确,但TypeScrip编译器在最后两行报告如下:

Argument of type '{ a: string; }' is not assignable to parameter of type 'PropsA & XType<string>'.
  Property 'x' is missing in type '{ a: string; }' but required in type 'XType<string>'.ts(2345)

Argument of type '{ b: string; }' is not assignable to parameter of type '{ b: string; } & XType<number>'.
  Property 'x' is missing in type '{ b: string; }' but required in type 'XType<number>'.ts(2345)

我try 了许多方法,以确保我可以在不显式指定类型的情况下调用extractTypes,并且仍然确保该函数返回的方法只接受{ a: string }{ b: string },而不是{ a: string; x: string }{ b: string; x: number },但都无济于事.

有没有什么方法可以在不要求显式指定extractTypes的泛型类型的情况下实现这一点?

我想我需要找到一种方法,通过从一个类型(XType)中减go 另一个类型(Props)来创建一个类型.我试过打Omit<Props, keyof XType<T>>,但在这里打不通.

谢谢!

ASIM

推荐答案

我只会简单地延长XType人.但这将迫使您在内部断言一个类型.

// adding a default for convenience
type XType<T = unknown> = {
  x: T;
};

function extractTypes<Props extends XType>(Component: React.FC<Props>) {
  // simply index and omit keys in `Props`
  return (props: Omit<Props, keyof XType>, value: Props['x']) => {
    Component({ ...(props as Props), x: value });
    //    assertion --------------
  };
}

playground

如果希望在将引用作为props 传递时,额外的属性判断也起作用,可以使用Omit<Props, keyof XType> & {[k in keyof XType]?: never},但考虑到人们使用Reaction的方式,这可能有些过分了.


顺便说一句,合并这两个泛型并不是绝对必要的,而且您的原始设计更安全,因为删除x: value会产生错误

 function extractTypes<Props, T>(Component: React.FC<Props & XType<T>>) {
   return (props: Omit<Props, keyof XType>, value: T) => {
     Component({ ...(props as Props), x: value });
    //    assertion ---------------
   };
 }

我不知道为什么,因为Props被推断为{a: string} & XType<string

Typescript相关问答推荐

如何推断类方法未知返回类型并在属性中使用它

用泛型类型覆盖父类函数导致类型y中的Property x不能赋给基类型Parent中的相同属性."'''''' "

根据另一个属性的值来推断属性的类型

TYPE FOR ARRAY,其中每个泛型元素是单独的键类型对,然后在该数组上循环

将对象的属性转换为正确类型和位置的函数参数

有没有办法在Zod中使用跨字段验证来判断其他字段,然后呈现条件

在Cypress中,您能找到表格中具有特定文本的第一行吗?

声明遵循映射类型的接口

如何扩展RxJS?

如何在具有嵌套数组的接口中允许新属性

可赋值给类型的类型,从不赋值

顶点堆叠的图表条形图未在正确的x轴上显示

打字:注解`是字符串`而不是`布尔`?

如何正确键入泛型相对记录值类型?

如何填写Partial的一些属性并让类型系统知道它?

如何创建允许使用带有联合类型参数的Array.from()的TS函数?

对于通过 Axios 获取的数据数组,属性map在类型never上不存在

如何为字符串模板文字创建类型保护

如何强制对象数组中的对象属性具有非空字符串值?

从接口推断模板参数?