[英]empty object {} is not of type {} in typescript
I have the following helper method that returns a wrapped react component. 我有以下帮助程序方法,该方法返回一个包装好的react组件。
export function wrapComponentInContext<T extends object = {}>(
Comp: React.FunctionComponent<T>,
props: T = {}) { // ERROR: Type '{}' is not assignable to type 'T'
const mockSetter = jest.fn(() => { });
const mockContext: ContextDefaultValue = ["context", mockSetter];
return (
<Provider value={mockContext}>
<Comp {...props}/>
</Provider>
);
}
I want to default to an empty object if no argument is supplied. 如果没有提供任何参数,我想默认为空对象。
Here is an even simpler example 这是一个更简单的例子
So it seems an empty object is not of type {}
which is confusing. 因此,似乎一个空对象不是{}
类型的,这很令人困惑。
Why 为什么
A generic function needs to be valid for any possible T
passed into the function. 泛型函数必须对传递给该函数的任何可能的T
有效。 T extends object
means T
can be any object type, so it could for example be { foo: string }
and {}
would not be a valid default for this type. T extends object
意味着T
可以是任何对象类型,因此它可以是{ foo: string }
而{}
对此类型不是有效的默认值。
The default type for the type parameter in no way correlates with the default for the parameter. type参数的默认类型与该参数的默认值没有任何关系。 You can call with an explicit type argument and without a default thus producing a conflict between the default value {}
and T
passed in. Or you can just omit the default and pass in a component with required props: 您可以使用显式类型参数进行调用,而无需使用默认参数,从而在默认值{}
和传入的T
之间产生冲突。或者您可以忽略默认值并使用必需的props传递组件:
declare function comp(o: { p: string }): void;
wrapComponentInContext(comp)
You can use a type assertion to force {}
into T
: 您可以使用类型断言来强制{}
进入T
:
export function wrapComponentInContext<T extends object = {}>(Comp: React.FunctionComponent<T>, props: T = {} as T) {
}
But this will expose you to the potential issues I highlighted above. 但是,这会使您面临我上面强调的潜在问题。 You can add a dedicated overload for a component for which {}
is a valid default, although getting it to work as expected requires a bit of conditional types because of the contravariant nature of function parameters: 您可以为{}
是有效的默认值的组件添加专用的重载,尽管由于函数参数的相反性质,使其按预期方式工作需要一些条件类型:
declare function compOptional(o: { p?: string }): void;
declare function comp(o: { p: string }): void;
export function wrapComponentInContext<T>(Comp: React.FunctionComponent<T> & ({} extends T ? {} : "Provide default props as component requires some"))
export function wrapComponentInContext<T extends object>(Comp: React.FunctionComponent<T>, props: T)
export function wrapComponentInContext<T extends object = {}>(Comp: React.FunctionComponent<T>, props: T = {} as T) {
}
wrapComponentInContext(comp) // Type '(o: { p: string; }) => void' is not assignable to type '"Provide default props as component requires some"'.
wrapComponentInContext(compOptional)
wrapComponentInContext(comp, { p: "" })
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.