You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中实现基于类静态check方法的返回类型自动收窄?

如何在TypeScript中实现基于类静态check方法的返回类型自动收窄?

我有一批带有static check方法的类,想在wrap方法中找到匹配的类并返回其实例,这种架构非常适合我的OOP需求。我之前在JavaScript中是这么实现的:

class A {
    static check = arg => typeof arg == "number"
    constructor(arg) { this.value = arg}
    log = () => console.log("A/", this.value)
}

class B {
    static check = arg => typeof arg == "string"
    constructor(arg) { this.note = arg }
    log = () => console.log("B/", this.note)
}

function wrap(arg, classes) {
    for (const Class of classes) 
        if (Class.check(arg))
            return new Class(arg)
}

const classes = [A, B]

wrap("adaptive", classes).log()
wrap(999, classes).log()

最近我想试试用TypeScript来实现,期望wrap函数的调用能自动推断返回类型(毕竟TypeScript就是管类型的),但实际却没做到。我目前能写出的最接近的代码是这样的:

type PayloadA = number
type PayloadB = string
type PayloadGeneric = PayloadA | PayloadB

class A {
    static check(arg:PayloadGeneric): arg is PayloadA {
        return typeof arg == "number"
    }
    value: number
    constructor(arg: PayloadA) { this.value = arg}
    log = () => console.log("A/", this.value)
}

class B {
    static check(arg:PayloadGeneric): arg is PayloadB {
        return typeof arg == "string"
    }
    note: string
    constructor(arg: PayloadB) { this.note = arg}
    log = () => console.log("B/", this.note)
}

function wrap(arg: PayloadGeneric) {
    if (A.check(arg)) {   // understands that arg is number
        return new A(arg) // and that arg is suitable for PayloadA
    } 
    if (B.check(arg)) {   // understands that arg is string
        return new B(arg) // and that arg is suitable for PayloadB
    }
}

const instanceA = wrap(999) // but here it doesn't understand the type
const instanceB = wrap("adaptive") // neither here

(我知道PayloadA和PayloadB看起来有点多余,毕竟它们就是number和string,但这里只是用简单类型举例子,实际场景中会是自定义接口和断言,用类型别名是为了更清晰地表达我的意图)

你看,wrap函数只接受PayloadA或PayloadB类型的参数,内部的两个if判断里,TypeScript能正确识别arg的类型(比如A.check后知道arg是number,能匹配A的构造函数),但到了调用wrap的时候,它却没法自动推断返回的是A还是B的实例,甚至还会认为可能返回undefined——但逻辑上我已经处理了所有可能的输入情况。

我的问题是:明明已经覆盖了所有场景,TypeScript却无法识别,该怎么修复?我想要实现返回类型的自动收窄,而且不想硬编码返回类型为A | B,因为传入的类列表可能会变化:如果没有类的check方法匹配,返回类型应该是undefined;如果有匹配的,就自动推断出对应的类实例类型。

备注:内容来源于stack exchange,提问作者Vagif VALIYEV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:18:06