【问题标题】:Typescript: type guard across properties in an interfaceTypescript:跨接口中的属性进行类型保护
【发布时间】:2020-12-16 19:26:38
【问题描述】:

在打字稿中,我可以声明一个函数类型保护来检查属性是否为空,类似于以下内容:

interface IApiResponse<TRecord> {
  readonly isDefined: boolean;
  readonly record: TRecord | null;
}

const responseHasRecordDefined = 
  <TRecord>(apiResponse: IApiResponse<TRecord>): apiResponse.record is TRecord => apiResponse.isDefined;

但是我想知道是否有一种方法可以只使用一个接口定义来完成相同的任务?

类似于:

interface IApiResponse<TRecord> {
  readonly record: TRecord | null;
  readonly isDefined: this.record is TRecord;
}

编辑:

正如 Ryan 在 cmets 中指出的那样,这种初始情况很容易通过空检查来处理。因此,我添加了另一个需要某种类型保护而不是简单的空检查的问题示例。

interface IResponseTypeA {
  // Anything can be in here
}

interface IResponseTypeB {
  // Anything can be in here
}

interface IApiResponse {
  readonly record: IResponseTypeA | IResponseTypeB;
  readonly isTypeA: this.record is IResponseTypeA;
}

【问题讨论】:

  • 您是否有理由检查类型保护中的布尔值,而不是直接检查 record 字段是否为 null?例如,这就是您无法控制的某些 API 返回的内容吗?
  • 你是对的,在我给出的示例中,我可以检查record 字段是否为null。我已经更新了这个问题以包含一个更通用的情况,其中两种类型的定义没有那么好,以至于像空检查这样的东西会起作用。

标签: javascript typescript typescript-typings


【解决方案1】:

我不确定我是否以正确的方式理解了这个问题,但你可以这样做

type IApiResponse =  {
  readonly record: IResponseTypeA;
  readonly isTypeA: true;
} | {
  readonly record: IResponseTypeB;
  readonly isTypeA: false;
}

然后如果你有一个函数,这将根据变量推断类型

function foo(bar: IApiResponse){
    if (bar.isTypeA){
     /// record is not from type IResponseTypeA
    }
}

【讨论】:

  • 这正是我一直在寻找的......这很愚蠢,因为我的项目中已经有了这种形式的声明,用于一个奇怪的反应组件的道具?‍♂️
猜你喜欢
  • 2020-02-01
  • 2021-12-10
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 2021-06-28
  • 1970-01-01
相关资源
最近更新 更多