TypeScript声明合并扩展Stripe.Subscription字段失败求助
为Stripe.Subscription扩展自定义字段role的正确方法
问题
尝试用TypeScript声明合并给Stripe.Subscription添加role字段时失败,出现两个问题:
- 扩展接口后访问
subscription.role仍触发TS2339错误 - 尝试修改
Stripe.Subscription.prototype时,报错“TS2339: Property 'Subscription' does not exist on type 'typeof import("stripe")'”
原尝试代码:
import Stripe from 'stripe'; export {}; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace namespace Stripe { interface Subscription { role: string; } } } // 报错行 Stripe.Subscription.prototype.role: string = this['role'];
访问字段时的错误场景:
const subscription: Stripe.Subscription = getSubscription(); subscription.role; // TS2339: Property 'role' does not exist on type 'Subscription'.
解决方案
1. 正确扩展模块内的Stripe.Subscription接口
stripe-node的类型定义采用模块导出,不是全局命名空间。需要通过模块扩展来合并声明,而非全局命名空间扩展。
创建一个类型声明文件(如src/stripe.d.ts),内容如下:
import 'stripe'; declare module 'stripe' { namespace Stripe { interface Subscription { role: string; } } }
2. 不要尝试修改原型
Stripe.Subscription对应的是Stripe API返回的普通JSON对象,不是类实例,因此无法通过修改prototype添加属性。可以通过以下方式处理:
- 类型断言:如果确定返回的订阅对象包含
role字段,直接断言类型const subscription = getSubscription() as Stripe.Subscription; subscription.role; // 类型检查通过 - 手动赋值:在获取原始订阅数据后,添加
role字段并断言类型const rawSub = await stripe.subscriptions.retrieve('sub_xxx'); const subscription = { ...rawSub, role: 'premium' } as Stripe.Subscription;
3. 确保类型文件被识别
检查tsconfig.json的include配置,确保包含了你的声明文件,比如:
{ "include": ["src/**/*", "src/stripe.d.ts"] }
核心原因
stripe-node的类型是在stripe模块内部定义的,之前用全局Stripe命名空间扩展的方式无法和模块内的接口合并,必须使用declare module 'stripe'来扩展模块内的接口,TypeScript才能正确合并类型声明。
内容的提问来源于stack exchange,提问作者vovahost
相关产品推荐
相关产品推荐

