打字稿无法解析联合类型的属性

时间:2020-02-05 14:17:06

标签: typescript types

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

我有以下界面:

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/*"
  ]
}

预先感谢

2 个答案:

答案 0 :(得分:1)

您的逻辑有缺陷。 SearchQuerySearchLocationQuerySearchBrandQuery。其中之一具有属性availability。因此,编译器会抱怨availability不是两种类型的并集,这会导致错误

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

因此,您必须检查其类型,例如in运算符,例如

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

答案 1 :(得分:1)

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

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

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

...由于在您尝试使用availability时,警卫人员已经证明您正在处理SearchBrandQuery,因此TypeScript编译器可以缩小类型。


或者,您可以使用intersection type来拥有所有属性:

export type SearchQuery = SearchLocationQuery & SearchBrandQuery;

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