打字稿文字字符串和联合类型匹配两个接口

时间:2021-03-03 15:16:15

标签: typescript

我正在尝试为 API 响应创建类型,并根据 error 属性更改 API 响应的详细信息。

我有这些类型:

export interface ResponseErrorUnknown {
  code: number;
  error: string & {};
  message: string;
  details: any;
}

export interface ResponseErrorFailedValidators extends ResponseError {
  error: 'failedValidators';
  details: {
    errors: Array<{
      field: string;
      validator: string;
    }>;
  }
}

export type ResponseError = ResponseErrorFailedValidators | ResponseErrorUnknown;

现在,当我收到 API 错误并且是 failedValidators 错误时,我希望我的 IDE 知道 details 属性的格式类似于接口 ResponseErrorFailedValidators

就像这样:

if (apiError.error === 'failedValidators') {
  // apiError.details.errors should come up as a suggestion
} else {
  // apiError.details can be anything, because it matched the ResponseErrorUnknown
}

我在互联网上搜索 Typescript 的联合和文字文档,但找不到我要找的东西。所以我希望一切顺利!

提前致谢!

1 个答案:

答案 0 :(得分:0)

据我所知,您希望能够键入检查以下代码

  if (apiError.error === 'failedValidators') {
   // apiError.details.errors should come up as a suggestion
  } else {
   // apiError.details can be anything, because it matched the ResponseErrorUnknown
  }

所以带条件块。

if (apiError.error === 'failedValidators') {

Typescript 将 apiError 推断为 ResponseErrorFailedValidators

我建议使用 User-Defined Type Guards link

在您的情况下,解决方案是定义您的自定义类型保护

const apiError: any = {
 error: "failedValidators",
 details: {
  errors: [],
 },
};

function isFailedValidator(
 unknowError: any
): unknowError is ResponseErrorFailedValidators {
  if ("error" in unknowError) {
   return unknowError.error === "failedValidators";
  }

  return false;
}

if (isFailedValidator(apiError)) {
 // apiError.details.errors should come up as a suggestion
 apiError.details
} else {
 // apiError.details can be anything, because it matched the ResponseErrorUnknown
}

为了完全理解这是如何工作的,您需要了解 is 运算符。如您所见,函数体本质上是一个谓词,返回 truefalse。如果它返回 true,则作为参数传递的值是您声明的某种类型。