【问题标题】:Why TypeScript excepts a correct return of a overriden method, even though it's not reachable?为什么 TypeScript 接受被覆盖方法的正确返回,即使它不可访问?
【发布时间】:2020-03-26 21:43:07
【问题描述】:

我已经实现了一个抽象的通用 RESTClient。有时并非所有 REST 操作都已实现,因此我想在这种情况下抛出错误。

如果我重写了 TypeScript 期望我返回指定类型的方法,即使我抛出了错误。如果我添加return null,它会编译,但返回是无法访问的。

export class RESTClient<E extends { id: number }, D = Omit<E, 'id'>> extends Client {
  protected path: string;
  public constructor(path: string, token?: string) {
    super(token);
    this.path = path;
  }

  public update(entity: E) {
    return this.clientInstance.put<E>(`${this.path}/${entity.id}`, entity);
  }
}

export class ItemClient extends RESTClient<Item> {
  public constructor(token?: string) {
    super('items', token);
  }

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  public delete(_entity: Item) {
    throw new Error('Not supported by API');
  }
}

如何在 TypeScript(版本 3.7.2)中正确实现这一点?

【问题讨论】:

    标签: typescript overloading abstract-class


    【解决方案1】:

    您可以使用never 作为实现方法的返回类型。它可以分配给其他所有类型:

    interface Item { 
      id: number;
    }
    
    export class RESTClient<E extends { id: number }> {
      public update(entity: E) {
        return entity;
      }
    }
    
    export class ItemClient extends RESTClient<Item> {
      public update(entity: Item): never {
        throw new Error('Not supported by API');
      }
    }
    

    documentation的适当摘录:

    never 类型是每个类型的子类型,并且可以分配给每个类型;但是,没有类型是never 的子类型或可分配给nevernever 本身除外)。即使any 也不能分配给never

    【讨论】:

    • 哦,我不知道在这种情况下never是允许的,因为我认为方法的签名必须与继承的匹配。谢谢你教我这个! (终于可以用这个很酷的never类型了)
    猜你喜欢
    • 2013-12-24
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 2013-03-08
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多