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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:45:34