【问题标题】:Typescript check generic type for interface打字稿检查接口的泛型类型
【发布时间】:2018-12-27 03:19:05
【问题描述】:

在我的 Angular 6 文件中,我定义了一个接口,然后在一个采用通用参数 T 的方法中,我想确定 T 是否在运行时实现该接口。这可能吗?

我尝试过if (T instanceof INetworkObject),但编译器不喜欢这样。

export interface INetworkObject {
    fixNetworkObject(): void;
}

protected getTypedItem<T>(endpoint: string, C: { new(): T }): Observable<T> {
    return this.http.get<T>(`${this.baseUrl}/${endpoint}`)
        .pipe(map(element => {
            if (!element) {
                return null;
            }

            const ret = Object.assign(new C(), element);

            if (T.type instanceof NetworkObject) {

            }

            // This ugliness is what I'm doing now
            if (typeof ret['fixNetworkObject'] === 'function') {
                ret['fixNetworkObject']();
            }

基本上我要做的是在ret 上调用fixNetworkObject,如果它实现了该接口。

【问题讨论】:

  • @IngoBürk 我对其中的大多数都很熟悉,但它是通用的这一事实是导致我出现问题的原因。 T 不会总是实现 NetworkObject。

标签: typescript typescript-generics


【解决方案1】:

很遗憾,您不能使用instanceof,因为接口在运行时不存在。你需要像这样声明一个类型保护(参见Advanced Types Documentation):

function isINetworkObject(obj: any): obj is INetworkObject {
  return typeof obj.fixNetworkObject === 'function';
}

然后修改你的 if:

if (isINetworkObkect(ret)) {
  ret.fixNetworkObject();
}

【讨论】:

  • 假设 T 总是 纵向延伸。我不知道这里。有时会,有时不会。
  • 我不这么认为,因为Fish有接口,对吧?我不总是有这种类型的东西。这就是为什么我需要它作为运行时检查。
  • 所以我知道它是如何确定它是否是那个类。但是那里的ret 是泛型类型怎么知道它可以调用fixNetworkObject()。看起来应该是打字稿构建错误!
  • 这就是类型保护的工作原理。特殊的is 返回类型意味着下面的函数将检查用户认为安全的类型安全。如果函数返回 true,则参数指定 is 所讨论的类型。然后,如果您有一个依赖于这些is 类型的if,它会将变量的类型安全应用于if 的代码块(或者else,如果您执行了逆操作或其他操作)。
  • 它也足够聪明地处理返回,所以你可以这样做:if (!isINetworkObkect(ret)) return; 并且下面函数中的所有代码都将使用该类型。
猜你喜欢
  • 2017-09-26
  • 2021-11-26
  • 1970-01-01
  • 2020-04-13
  • 2019-01-16
  • 1970-01-01
  • 2018-11-03
  • 2020-05-09
  • 1970-01-01
相关资源
最近更新 更多