首页 > 解决方案 > Typescript:跨接口中的属性进行类型保护

问题描述

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

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 在评论中指出的那样,这种初始情况很容易通过空检查来处理。因此,我添加了另一个需要某种类型保护而不是简单的空检查的问题示例。

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;
}

标签: javascripttypescripttypescript-typings

解决方案


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

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
    }
}

推荐阅读