Skip to content

Export Decimal as a type in the Stripe namespace#2634

Open
jar-stripe wants to merge 5 commits intomasterfrom
jar/export-decimal-type
Open

Export Decimal as a type in the Stripe namespace#2634
jar-stripe wants to merge 5 commits intomasterfrom
jar/export-decimal-type

Conversation

@jar-stripe
Copy link
Copy Markdown
Contributor

Why?

PR #2626 fixed the runtime export of Stripe.Decimal, but using it as a TypeScript type annotation doesn't work:

const d: Stripe.Decimal = Stripe.Decimal.from('1.0');
// TS2749: 'Stripe.Decimal' refers to a value, but is being used as a type here.

This is because Decimal was added to the Stripe class as a static property (value) but not to the Stripe namespace (type). TypeScript needs both for Stripe.Decimal to work in both value and type positions.

What?

  • Added export type Decimal = import('./shared.js').Decimal to the Stripe namespace in stripe.core.ts and stripe.esm.node.ts
  • Added export {Decimal} from './shared.js' as a named ESM module export, enabling import { Decimal } from 'stripe'
  • Added a declare namespace StripeConstructor with the Decimal type to stripe.cjs.node.ts, so CJS consumers can also use Stripe.Decimal as a type

After this change, all of these work:

  • ESM: const d: Stripe.Decimal = Stripe.Decimal.from('1.0')
  • ESM: import { Decimal } from 'stripe' as a named type import
  • CJS: const d: Stripe.Decimal = Stripe.Decimal.from('1.0')

Uses import() type syntax to avoid circular definition issues (the class static property Stripe.Decimal and the namespace type Stripe.Decimal would otherwise create a circular reference).

See Also

The Decimal class was accessible as a runtime value via Stripe.Decimal
(after #2626), but could not be used as a TypeScript type annotation.
Writing `const d: Stripe.Decimal = Stripe.Decimal.from('1.0')` produced
TS2749: "'Stripe.Decimal' refers to a value, but is being used as a
type here."

This adds Decimal to the Stripe namespace as a type in three places:
- stripe.core.ts (shared namespace definition)
- stripe.esm.node.ts (namespace + named module export)
- stripe.cjs.node.ts (namespace on the CJS export wrapper)

After this change, all of these work:
- ESM: `const d: Stripe.Decimal = Stripe.Decimal.from('1.0')`
- ESM: `import { Decimal } from 'stripe'` (named import)
- CJS: `const d: Stripe.Decimal = Stripe.Decimal.from('1.0')`

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Committed-By-Agent: claude
@jar-stripe jar-stripe marked this pull request as ready for review March 27, 2026 00:42
@jar-stripe jar-stripe requested a review from a team as a code owner March 27, 2026 00:42
@jar-stripe jar-stripe requested review from a team, Copilot and prathmesh-stripe and removed request for a team March 27, 2026 00:42
The declare namespace uses import() type syntax which is self-contained;
the file-scope import isn't reachable from inside a namespace block.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Committed-By-Agent: claude
@xavdid-stripe
Copy link
Copy Markdown
Member

xavdid-stripe commented Mar 27, 2026

Prathmesh can review since he's got a lot of context here, but you should add lines in the test projects to confirm this behavior.

Also, do you want to fold in the changes from #2633 and we can close that PR?

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes TypeScript usability of Stripe.Decimal by ensuring Decimal exists in the Stripe namespace (type position) in addition to the existing static property (value position), and exposes Decimal as a named ESM export.

Changes:

  • Add Stripe.Decimal as a type alias to shared.Decimal in stripe.core.ts and stripe.esm.node.ts.
  • Add a named ESM export Decimal from the Node ESM entrypoint.
  • Add a CJS-side merged namespace StripeConstructor.Decimal so Stripe.Decimal can be used as a type when importing via require().

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/stripe.esm.node.ts Adds Stripe.Decimal namespace type + re-exports Decimal as a named ESM export.
src/stripe.core.ts Adds Stripe.Decimal namespace type so Stripe.Decimal works in type positions.
src/stripe.cjs.node.ts Adds merged namespace type StripeConstructor.Decimal for CJS consumers’ type annotations.
Comments suppressed due to low confidence (1)

src/stripe.cjs.node.ts:3

  • Decimal is imported but never used. With the repo-wide no-unused-vars rule enabled, this will fail lint; remove the import (or convert it to a type-only import if you end up needing it for declarations).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +42 to 44
export type Decimal = import('./shared.js').Decimal;
}
export = StripeConstructor;
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is meant to enable Stripe.Decimal in type positions for CJS consumers, but there doesn’t appear to be a TypeScript compile-time test that exercises the CJS require('stripe') typing path (e.g., const Stripe = require('stripe'); const d: Stripe.Decimal = Stripe.Decimal.from('1.0');). Adding a type test would prevent regressions.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no existing CJS TypeScript test project — only a plain JS one. Adding a CJS TS test project is tracked separately. The ESM type tests cover Stripe.Decimal as a type annotation.

Comment on lines 2456 to +2466
@@ -2461,4 +2463,5 @@ export declare namespace Stripe {

Stripe.initialize(new NodePlatformFunctions());

export {Decimal} from './shared.js';
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new Stripe.Decimal namespace type and the new named export Decimal are both type-surface changes; consider adding/adjusting TypeScript compile-time tests to cover the intended usage (e.g., const d: Stripe.Decimal = Stripe.Decimal.from('1.0') and import type {Decimal} from 'stripe') so this doesn’t regress again.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — added const d: Stripe.Decimal = Stripe.Decimal.from('1.0') to both testProjects/types and mjs-ts, plus import type { Decimal } from 'stripe' in mjs-ts.

- Narrow CJS namespace comment to accurately reflect what's exported (only
  Decimal, not Account etc.)
- Add compile-time type annotation tests for Stripe.Decimal in both
  testProjects/types (ESM) and testProjects/mjs-ts (ESM+TS runtime)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Committed-By-Agent: claude
@jar-stripe jar-stripe enabled auto-merge (squash) March 27, 2026 01:28
…omments

Delete the declaration-merging example and import example that referenced
the old `@stripe/apps-extensibility-sdk/stdlib` module name. These
comments are no longer accurate now that Decimal lives in `stripe`.

Folds in the intent of #2633 (which renamed the references); the
resolution is to remove the comments entirely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Committed-By-Agent: claude
Verify `import type { Decimal } from 'stripe'` works alongside the
existing `Stripe.Decimal` namespace type test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Committed-By-Agent: claude
@jar-stripe
Copy link
Copy Markdown
Contributor Author

Prathmesh can review since he's got a lot of context here, but you should add lines in the test projects to confirm this behavior.

Also, do you want to fold in the changes from #2633 and we can close that PR?

yep! both should be done!


Stripe.initialize(new NodePlatformFunctions());

export {Decimal} from './shared.js';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want to directly export Decimal class? Or should it live under Stripe namespace like the rest of the exported clases?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants