简体   繁体   English

声明后从赋值推断TypeScript类型

[英]Infer TypeScript type from assignment after declaration

When writing tests for React components, it's typical to initialize a component wrapper (say wrapper ) in a beforeEach block and then use it in the subsequent tests. 在编写针对React组件的测试时,通常会在beforeEach块中初始化组件包装器(例如wrapper ),然后在后续测试中使用它。 However, in order to do this, you have to declare wrapper before its assignment and give it an explicit type or else TypeScript will complain about the lack of a type. 但是,为了做到这一点,您必须在分配wrapper之前声明wrapper并为其指定显式类型,否则TypeScript将抱怨缺少类型。 Unfortunately, this type can be quite complex to figure out / write out. 不幸的是,这种类型的查找/写出可能非常复杂。

In the example below, is there any way to 'delay' TypeScript from complaining about the lack of a type for wrapper in the example below and get it to infer the type from the place where wrapper is assigned? 在下面的示例中,是否有任何方法可以“延迟” TypeScript,避免在下面的示例中抱怨wrapper缺少类型,并从分配wrapper的位置推断出该类型?

Alternatively, is there a better pattern to lay out variables which makes typing easier? 或者,是否有更好的模式来布置变量以简化键入?

describe('suite', () => {
  // will trigger a no implicit any error
  // but it's quite complex to manually write out the type here
  let wrapper;

  beforeEach(() => {
    const SomeElement = complexFunctionWithGenericParams(someParam);

    // ideally, we want TS to infer the type of `wrapper` from this statement
    wrapper = mountComponent(<SomeElement />);
  })

  it('does something', () => {
    expect(wrapper.state.someField).toBe(5);
  }
}

There's no way to infer a type from assignment because it should be inferred at declaration time. 无法从赋值推断类型,因为它应该在声明时推断出来。 The point of local variables in tests is that they can be used between blocks, this means that they can be assigned multiple times. 测试中局部变量的重点是可以在块之间使用它们,这意味着可以多次分配它们。 Even if this kind of inference were possible, it would be ambiguous: 即使可以进行这种推断,也将是模棱两可的:

let foo; // is the type supposed to be a number, or a string, or both, or any?

it('...', () => {
  foo = 1;
});

it('...', () => {
  foo = 'foo';
});

So the type should be specified explicitly, eg with ReturnType : 因此,应明确指定类型,例如,使用ReturnType

let wrapper: ReturnType<typeof mount>;

mount is generic, return type may vary, ReturnType may be more complicated with generic functions . mount是通用的,返回类型可能会有所不同, 使用通用函数ReturnType可能会更复杂

Since Enzyme shallow and mount should be explicitly specified with generic parameters: 由于应使用通用参数显式指定酶shallowmount

wrapper = mount<typeof SomeElement, ISomeElementProps>(<SomeElement />);

It's more straightforward to specify generic type directly, since it's known what type it is ( ReactWrapper ): 直接指定泛型类型更直接,因为知道它是什么类型( ReactWrapper ):

let wrapper: Enzyme.ReactWrapper<ISomeElementProps, ISomeElementState, typeof SomeElement>

Although not an entirely different pattern, the following has helped get rid of the said warnings in a similar situation. 尽管不是完全不同的模式,但以下内容有助于在类似情况下摆脱上述警告。

import { shallow, mount, ReactWrapper } from 'enzyme'

describe('suite', () => {
  let wrapper: ReactWrapper;

  beforeEach(() => {
    ...
    wrapper = mount or shallow 
  })

  it('does something', () => {
    ...
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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