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

TypeScript参数化类型编译通过是编译器bug还是程序合理?

问题原因

TypeScript 采用结构类型系统判断类型兼容性,而非标称类型系统:只要两个类型的实例结构完全一致,TS 就会认为二者互相兼容。
你代码里的泛型参数T仅在构造函数的入参中使用,没有被作为实例的属性保留,因此RegularString<"^...$">和RegularString<"^.$">的实例结构完全相同:都包含一个私有value字符串属性和一个toString方法,TS 自然不会判定赋值类型错误。

修复方案

只需要将泛型参数T绑定到实例属性上,让不同的T产生不同的实例结构即可,常见两种实现:

方案1:显式存储正则规则到实例

class RegularString<T extends string>
{
    // 新增pattern属性,类型绑定为T
    constructor(private readonly value: string, private readonly pattern: T)
    {
        if(!new RegExp(pattern).test(value))
            throw new Error("Given value does not conform to regex " + pattern + ". found: " + value)
    }

    toString()
    {
        return this.value
    }
}

const strLengthThree: RegularString<"^...$"> = new RegularString<"^...$">("ABC", "^...$") 
const strLengthOne:   RegularString<"^.$"> = strLengthThree // 此时就会触发预期的类型错误

方案2:使用幻影类型标记(不需要实际存储值)

如果不想对外暴露正则规则,也可以加一个仅用于类型区分的私有幻影属性,不需要赋值,不占用运行时空间:

class RegularString<T extends string>
{
    // 幻影属性,仅用于类型标记
    private readonly _typeMarker?: T
    constructor(private readonly value: string, regexPatternConstraint: T)
    {
        if(!new RegExp(regexPatternConstraint).test(value))
            throw new Error("Given value does not conform to regex " + regexPatternConstraint + ". found: " + value)
    }

    toString()
    {
        return this.value
    }
}

const strLengthThree: RegularString<"^...$"> = new RegularString<"^...$">("ABC", "^...$") 
const strLengthOne:   RegularString<"^.$"> = strLengthThree // 同样会触发预期的类型错误

内容的提问来源于stack exchange,提问作者Dejas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 02:21:01