简体   繁体   English

空脚本{}在打字稿中的类型不是{}

[英]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.

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