gpt4 book ai didi

Generics Inference when overriding a prop in higher order component(覆盖高阶组件中的道具时的泛型推理)

转载 作者:bug小助手 更新时间:2023-10-25 22:46:23 26 4
gpt4 key购买 nike



I have the following code:

我有以下代码:


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

CompA and CompB expect a and b properties along with all properties in XType.

CompA和CompB需要a和b属性以及XType中的所有属性。


The 3rd-last and 4th-last compile correctly, however the Typescript compiler complains on the last two lines as follows:

第三行和第四行可以正确编译,但是Typescript编译器在最后两行抱怨如下:


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)

I've tried many approaches to ensure that I can call extractTypes without specifying the types explicitly and still ensure that the method returned by this function accepts only { a: string } or { b: string } instead of { a: string; x: string } or { b: string; x: number }, but to no avail.

我尝试了许多方法来确保我可以在不显式指定类型的情况下调用fettTypes,并且仍然确保该函数返回的方法只接受{a:字符串}或{b:字符串},而不是{a:字符串;x:字符串}或{b:字符串;x:数字},但无济于事。


Is there any way I can accomplish this without requiring explicit specifying generic types for extractTypes?

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


I think I need to find a way to create a type by subtracting one type (XType) from another (Props). I've tried using Omit<Props, keyof XType<T>> but it doesn't work well here.

我想我需要找到一种方法,通过从一个类型(XType)中减去另一个类型(道具)来创建一个类型。我试过使用omit >,但在这里不能很好地工作。


Thanks!

谢谢!


Asim

ASIM


更多回答
优秀答案推荐

I would simply extend XType. This will force you to assert a type internally though.

我只需扩展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

操场


If you want excess property checking to also work when you pass a reference as props, you can use Omit<Props, keyof XType> & {[k in keyof XType]?: never} but this may be overkill given the way people use React.

如果希望在将引用作为道具传递时,额外的属性检查也起作用,可以使用omit &{[k in key of XType]?:ever},但考虑到人们使用Reaction的方式,这可能有些过分了。




As a side-note, merging the 2 generics was not strictly necessary and your original design is safer, because removing x: value will yield an error

顺便提一下,合并这两个泛型并不是绝对必要的,而且您的原始设计更安全,因为删除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 ---------------
};
}

I don't know why though because Props is inferred as {a: string} & XType<string

我不知道为什么,因为道具被推断为{a:字符串}&XType<字符串


更多回答

I can use the necessary assertion as suggested, but it also works for { ...props } as Props and even { } as Props. This is fine since I have control of this piece of code. But I want to know how can I properly use typescript such that I don't need to use such potentially code-breaking assertions. =/

我可以按照建议使用必要的断言,但它也适用于{...道具}作为道具,甚至{}作为道具。这很好,因为我已经控制了这段代码。但我想知道我如何正确地使用打字脚本,这样我就不需要使用这种潜在的代码破解断言。=/

Also, this is an over-simplified example. The requirement is to be able to infer the type of T used with XType. In my actual code, it has a function which accepts a parameter of type T. The second requirement is to be able to infer the actual type of props that were extended with XType and used in React.FC<>. I have a feeling that we should be able to infer these types within the function somehow.

此外,这也是一个过于简化的例子。要求能够推断XType使用的T的类型。在我的实际代码中,它有一个接受T类型参数的函数。第二个要求是能够推断使用XType扩展并在React.FC<>中使用的道具的实际类型。我有一种感觉,我们应该能够以某种方式在函数中推断出这些类型。

I was a bit pessimistic with my assertion. It's possible to only assert Props on props. When doing so, your original design with 2 generics works better. Try and experiment with your real use case. I don't like having multiple generics when I can avoid it but it does seem to help here.

我对我的断言有点悲观。只能在道具上声明道具。这样做时,您的原始设计中包含2个泛型的效果更好。试着用你的真实用例来做实验。当我可以避免的时候,我不喜欢有多个泛型,但它在这里似乎确实有帮助。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com