Export Decimal as a type in the Stripe namespace#2634
Export Decimal as a type in the Stripe namespace#2634jar-stripe wants to merge 5 commits intomasterfrom
Conversation
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
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
|
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? |
There was a problem hiding this comment.
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.Decimalas a type alias toshared.Decimalinstripe.core.tsandstripe.esm.node.ts. - Add a named ESM export
Decimalfrom the Node ESM entrypoint. - Add a CJS-side merged namespace
StripeConstructor.DecimalsoStripe.Decimalcan be used as a type when importing viarequire().
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
Decimalis imported but never used. With the repo-wideno-unused-varsrule enabled, this will fail lint; remove the import (or convert it to atype-only import if you end up needing it for declarations).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export type Decimal = import('./shared.js').Decimal; | ||
| } | ||
| export = StripeConstructor; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
| @@ -2461,4 +2463,5 @@ export declare namespace Stripe { | |||
|
|
|||
| Stripe.initialize(new NodePlatformFunctions()); | |||
|
|
|||
| export {Decimal} from './shared.js'; | |||
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
…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
yep! both should be done! |
|
|
||
| Stripe.initialize(new NodePlatformFunctions()); | ||
|
|
||
| export {Decimal} from './shared.js'; |
There was a problem hiding this comment.
Do we really want to directly export Decimal class? Or should it live under Stripe namespace like the rest of the exported clases?
Why?
PR #2626 fixed the runtime export of
Stripe.Decimal, but using it as a TypeScript type annotation doesn't work:This is because
Decimalwas added to theStripeclass as a static property (value) but not to theStripenamespace (type). TypeScript needs both forStripe.Decimalto work in both value and type positions.What?
export type Decimal = import('./shared.js').Decimalto theStripenamespace instripe.core.tsandstripe.esm.node.tsexport {Decimal} from './shared.js'as a named ESM module export, enablingimport { Decimal } from 'stripe'declare namespace StripeConstructorwith theDecimaltype tostripe.cjs.node.ts, so CJS consumers can also useStripe.Decimalas a typeAfter this change, all of these work:
const d: Stripe.Decimal = Stripe.Decimal.from('1.0')import { Decimal } from 'stripe'as a named type importconst d: Stripe.Decimal = Stripe.Decimal.from('1.0')Uses
import()type syntax to avoid circular definition issues (the class static propertyStripe.Decimaland the namespace typeStripe.Decimalwould otherwise create a circular reference).See Also