为什么TypeScript不能正确返回重写的方法,即使它无法访问?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么TypeScript不能正确返回重写的方法,即使它无法访问?相关的知识,希望对你有一定的参考价值。

我已经实现了抽象的通用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');
  }
}

demo

如何在TypeScript(版本3.7.2)中正确实现它?

答案

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

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本身除外)。甚至never也无法分配给any

以上是关于为什么TypeScript不能正确返回重写的方法,即使它无法访问?的主要内容,如果未能解决你的问题,请参考以下文章

方法重写

方法重写

重载与重写问题

java Iterable接口为啥不能带泛型通配符?或者:为啥我不能重写 iterator() 方法为子类返回一个 Iterator?

为啥不能在 TypeScript 中导出类实例?

Java中子类重写父类的方法为啥返回值类型要小于等于父类方法的返回值类型?