联合类型在作为道具传递给组件时期望其他类型?

时间:2018-02-05 07:16:01

标签: reactjs typescript redux react-redux

我正在使用带有React的Typescript。

我正在从返回两种类型的API中检索数据:VirtualMachineDisk。后端负责区分资源类型,并根据查询结果返回两者的类型:

requestMoreInfo: (resourceType: string, resourceId: number): AppThunkAction<ResourceActions> => (dispatch, getState) => {
    let fetchResourceInfo = fetch('http://localhost:5004/GetResourceTypeInformation/' + resourceType + '/' + resourceId, {
        method: 'GET'
    })

我已经为我的Redux状态声明了一个联合类型:

export interface ResourceState {
    currentResourceInformation?: VirtualMachineInformation | DiskInformation;
}

我随后将响应转换为由传递给函数的资源类型确定的类型,并调度操作以更新我的组件状态。这就是我想到的错误。

if (resourceType == "Virtual Machine") {
  var vmResponse = response.json() as VirtualMachineInformation;

  dispatch({
    type: 'RECEIVE_RESOURCE_INFO',
    resourceInfo: vmResponse
  });
}
else if (resourceType == "Disk") {
  var diskResponse = response.json() as DiskInformation;
  dispatch({
    type: 'RECEIVE_RESOURCE_INFO',
    resourceInfo: diskResponse
  });
}

TypeScript似乎对此感到满意。但是,我正在尝试渲染子组件并将此更新状态作为prop:

传递
private requestResourceInformation = (resourceType: string, resourceId: number) => {
    this.props.requestMoreInfo(resourceType, resourceId);

    if (resourceType == "Virtual Machine") {
        return <VirtualMachineResource virtualMachine={this.props.currentResourceInformation} />
    }
}

这只是将表格与数据进行映射。

但是,我正在检索错误:

  Type 'VirtualMachineInformation | DiskInformation | undefined' is not assignable to type 'VirtualMachineInformation | undefined'.
    Type 'DiskInformation' is not assignable to type 'VirtualMachineInformation | undefined'.
      Type 'DiskInformation' is not assignable to type 'VirtualMachineInformation'.
        Property 'azureVmId' is missing in type 'DiskInformation

我认为这是因为TypeScript仍将该值视为联合类型,并且VirtualMachine类型中存在预期值,但Disk类型中不存在。

我在哪里错了?在检索数据后是否有明确的方法来声明联合的特定类型?

1 个答案:

答案 0 :(得分:1)

virtualMachine属性不接受DiskInformation接口作为值 - 这就是您的问题。 TypeScript编译器不知道编译时值的确切类型是什么,因此猜测类型是这三者之一:VirtualMachineInformationDiskInformationundefined

正如我在评论部分所写 - 您可以使用(至少)三种解决方案来解决您的问题:

  1. 使用类型断言 - https://www.typescriptlang.org/docs/handbook/basic-types.html#type-assertions - 您无法在 tsx 文件中使用<Type>value语法 return <SomeComponent prop={value as Type}></SomeComponent>

  2. 使用类型警卫https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards

    if ([check if type of the value is the Type]) { return [something else] } [TypeScript knows that the value IS NOT an instance of the Type here] return <SomeComponent prop={value}></SomeComponent>

  3. 使用重载 - http://www.typescriptlang.org/docs/handbook/functions.html#overloads

    class X { private y(x: "abc"): "cda"; private y(x: "cda"): "abc"; private y(x: string): string { [method logic] } }