如何正确为TypeScript泛型类方法getFormattedOrOriginal标注类型?
TypeScript泛型类中根据构造函数参数自动推导方法返回类型
我定义了如下TypeScript泛型类Test,构造函数接收类型为A的value参数,以及可选的、将A转换为B的formatter函数(B默认值为A)。我希望getFormattedOrOriginal方法能自动根据构造函数是否传入formatter,返回对应类型:未传入时返回A类型,传入时返回B类型。目前仅能通过this.value as unknown as B的类型断言实现,但这显然不是好方案,请问该如何正确为该方法标注类型?
原代码:
class Test<A, B = A> { constructor(private value: A, private formatter?: (x: A) => B) {} getFormattedOrOriginal(): B { return this.formatter ? this.formatter(this.value) : this.value; } } // 预期行为: new Test(3).getFormattedOrOriginal() === 3 new Test(3, x => x.toString()).getFormattedOrOriginal() === "3"
方案1:构造函数+方法重载(无安全风险)
通过重载明确不同参数组合下的类型关系,完全避免不安全的类型断言,逻辑清晰直观:
class Test<A> { private value: A; private formatter?: (x: A) => unknown; // 重载:未传入formatter的构造逻辑 constructor(value: A); // 重载:传入formatter时,推导转换后的类型B constructor<B>(value: A, formatter: (x: A) => B); // 构造函数核心实现 constructor(value: A, formatter?: (x: A) => unknown) { this.value = value; this.formatter = formatter; } // 重载:未传入formatter时返回原类型A getFormattedOrOriginal(): A; // 重载:传入formatter时返回转换后的类型B getFormattedOrOriginal<B>(): B; // 方法核心实现 getFormattedOrOriginal() { return this.formatter ? this.formatter(this.value) : this.value; } }
方案2:泛型条件类型(精确类型约束)
通过泛型参数结合条件类型,直接推导返回值类型。这里的类型断言是安全的,因为条件类型已经确保返回值与声明类型完全匹配:
class Test<A, F extends ((x: A) => unknown) | undefined = undefined> { constructor(private value: A, private formatter?: F) {} getFormattedOrOriginal(): F extends ((x: A) => infer B) ? B : A { return (this.formatter ? this.formatter(this.value) : this.value) as F extends ((x: A) => infer B) ? B : A; } }
验证效果
两种方案都能满足预期类型推导:
// 未传入formatter,返回number类型 const numTest = new Test(3); console.log(numTest.getFormattedOrOriginal() === 3); // true,类型为number // 传入formatter,返回string类型 const strTest = new Test(3, x => x.toString()); console.log(strTest.getFormattedOrOriginal() === "3"); // true,类型为string
方案对比
- 方案1更适合大多数场景,通过重载明确类型逻辑,无需任何断言,可读性强。
- 方案2适合需要严格控制泛型参数的场景,通过条件类型精确约束类型关系,断言仅用于辅助TypeScript推导,无安全风险。
内容的提问来源于stack exchange,提问作者hfdev
相关产品推荐
相关产品推荐

