方法重写似乎只能部分解决该方法的返回类型

人工智能 2026-07-08

我遇到了一个问题,似乎是关于被重写的方法的返回类型仅部分被解析的问题。

base.ts:

export default class BaseClass {
    constructor(
        private collection: string
    ) {

    }

    protected formatData(): string | number {
        return 15
    }

    findById(id: string) {
        return this.formatData()
    }
}

child.ts:

import BaseClass from './base.js'

class ChildClass extends BaseClass {
    constructor(collection: string) {
        super(collection)
    }

    override formatData() {
        return "yoghurt"
    }

    getDoctor() {
        return this.formatData()
    }
}

const myChild = new ChildClass('Kid')

测试用例:

const myChildsFavDrink = myChild.formatData()

const gotoSnack = myChildsFavDrink.concat(' and crisps')

const myChildsConfDrink = myChild.findById('')

const myDoctor = myChild.getDoctor()

让我感到意外的是以下几点:

  1. myChildsFavDrink 的类型是 string,如预期
  2. gotoSnack 可以正常工作,TypeScript没有带来任何问题
  3. myChildsConfDrink 的类型是 string | number(问题)
  4. myDoctor 的类型是 string

如果你实际运行这个简短的程序,myChildsConfDrink 将会正确地解析为 "yoghurt"。然而,TS似乎无法将 findById 方法的返回类型收窄为字符串,尽管在子类中已经显式重写了 formatData 方法。

AI对这个问题的解释本质上是 "TypeScript并非这样设计的",并且建议使用一个类型参数,这可以解决问题。但JavaScript 确实是这样设计的,因此我并不满意。

此外,在不知道这个问题/限制会发生的情况下,我已经开始为我的实际问题设计解决方案。我还没有准备好就此改变解决方案。遇到类似挫折的其他人都做了什么、如何解决?

有人能帮助解释这里潜在的、甚至是设计层面的问题吗?

解决方案

findById 在定义的位置是 string | number

覆盖另一个方法不会在派生类型中动态调整返回类型。

如果你想要 ChildClass.findById(): string,那么也覆盖它:

    override findById(id: string) {
        return this.formatData()
    }

或者甚至直接设置返回类型,这样更易读,并且能防止代码中的错误:

    override findById(id: string): string {
        return this.formatData()
    }
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章