Typescript 无法解析联合类型的属性

标签 typescript types

看来我不知道一些特定的编译问题。

我有这些接口(interface):

export interface CommonSearchQuery {
  text: string;
  category: number;
}

export type SearchBrandQuery = CommonSearchQuery & {
  availability: string;
}

export type SearchLocationQuery = CommonSearchQuery & {
  zip: string;
}

export type SearchQuery = SearchLocationQuery | SearchBrandQuery;

以及我的用法

export const fetchBrands = (params: SearchQuery, type: RequestType): Promise<any> => {
   console.log(params.availability);
}

我收到这个错误

TS2339: Property 'availability' does not exist on type 'SearchQuery'.
  Property 'availability' does not exist on type 'SearchLocationQuery'.

我的 ts 配置

{
  "compileOnSave": false,
  "compilerOptions": {
    "incremental": true,
    "jsx": "react",
    "lib": ["es6", "dom", "ES2017"],
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "noImplicitAny": false,
    "noImplicitThis": true,
    "strictNullChecks": true,
    "declaration": true,
    "baseUrl": ".",
    "esModuleInterop": true,
    "outDir": "dist"
  },
  "exclude": [
    "./dist/*",
    "./node_modules/*",
    "./stories/*"
  ]
}

提前致谢

最佳答案

因为您使用的是 union typeparams 将是 SearchLocationQuery SearchBrandQuery。只有 SearchBrandQuery 具有可用性SearchLocationQuery 没有。因此,在使用 params.availability 之前,您必须缩小 params 的类型,以便知道它具有该属性。

使用类型保护来实现这一点的一种方法。例如,这没有错误:

export const fetchBrands = (params: SearchQuery, type: RequestType): Promise<any> => {
    if ("availability" in params) {
        console.log(params.availability);
    }
    // ...
}

...因为当您尝试使用 availability 时, guard 已证明您正在处理 SearchBrandQuery,因此 TypeScript 编译器可以缩小范围类型。


或者,您可以使用 intersection type这将具有所有属性:

export type SearchQuery = SearchLocationQuery & SearchBrandQuery;

问题是,params 必须拥有所有属性,即使您在进行的搜索类型中不需要它们。我的印象是您不想这样做(可能是出于这个原因),因为您在其他地方使用了交集类型。

关于Typescript 无法解析联合类型的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60077800/

相关文章:

android - 兼容数据类型

c++ - C/C++ 中数据类型名称的含义

scala - 如何在参数定义中限制列表的最大长度?

mysql - 我如何将 typescript 回调转换为 promise

angular - ngx-charts:组合多种图表类型

javascript - 为什么在没有 shareReplay() 的情况下对可观察对象的两次订阅不会执行代码两次?

javascript - 为什么我必须为常规 "const"变量指定类型,而不是为 "const"循环中定义的 "for"变量指定类型?

typescript - 当 --module 为 'none' 时,如何使用 @types npm 存储库中的 TypeScript 定义文件

javascript - Aurelia - 为类实现三元并获取缺少的属性名称

c# - 如何找到两种类型中最小的可分配类型(重复)?