为啥 TypeScript 接受被覆盖方法的正确返回,即使它不可访问?

Posted

技术标签:

【中文标题】为啥 TypeScript 接受被覆盖方法的正确返回,即使它不可访问?【英文标题】: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)中正确实现这一点?

【问题讨论】:

【参考方案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类型了)

以上是关于为啥 TypeScript 接受被覆盖方法的正确返回,即使它不可访问?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 TypeScript 接受值作为数据类型?

为啥使用 jasmine 对 Node typescript 项目进行 Karma 单元测试会显示包含依赖项的覆盖范围?

TypeScript:如何正确键入一个接受承诺并按原样返回该承诺的函数

为啥 Typescript 不以正确的方式支持函数重载?

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

为啥 TypeScript 4 转译器没有看到这个不正确的类型传递给函数?