Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specify event.data.object as an alternative #758

Closed
merlinnot opened this issue Jan 10, 2020 · 17 comments
Closed

Specify event.data.object as an alternative #758

merlinnot opened this issue Jan 10, 2020 · 17 comments
Assignees
Labels
future type definition Marks issue related to outdated or incorrect TypeScript type definition

Comments

@merlinnot
Copy link

event.data.object is currently specified as an empty interface, which seems invalid. My understanding of the API is that it should be an alternative of all possibilities. Relevant code:

interface Data {
/**
* Object containing the API resource relevant to the event. For example, an `invoice.created` event will have a full [invoice object](https://stripe.com/docs/api#invoice_object) as the value of the object key.
*/
object: Data.Object;
/**
* Object containing the names of the attributes that have changed, and their previous values (sent along only with *.updated events).
*/
previous_attributes?: Data.PreviousAttributes;
}

@cjavilla-stripe
Copy link
Contributor

Thanks for highlighting, @merlinnot. We're going to look into this.

@rattrayalex-stripe
Copy link
Contributor

In the meantime, we recommend casting, as in this example:
https://github.com/stripe/stripe-node/master/8f3c3ec/examples/webhook-signing/typescript-node-express/express-ts.ts#L58-L60

const charge = event.data.object as Stripe.Charge;

In the future, we hope to type events well enough that checking event.type === 'charge.succeeded' will be enough for TS to infer that event.data.object is a Stripe.Charge.

@JamieS1211
Copy link

In reality this "data.object" value is one of ~49 different object types that can be returned via a webhook event. You will also notice that "type" is defined simply as a "string". In reality the type is one of ~151 different distinct strings.

If the "Stripe.Event" type was instead created via a union type of the ~49 different event types (based on the type of object returned), with each event type having a typing for the "type" key as a literal string union of all the relevant event events this should do the trick. I have actually gone through this process manually and created a d.ts file that will give "Stripe.DiscriminatedEvent" type that you can cast to and then discriminate with - I will put the link below. Please see attached image as an example below. I hope this helps anyone here as a or if it is of any use to update the typings.

https://github.com/JamieS1211/StripeDiscriminatedEventTyping/blob/master/StripeDiscriminatedEvents.d.ts

image

@JustinTRoss
Copy link

JustinTRoss commented Jun 20, 2020

Also worth noting, at a minimum, it would be helpful to add an [index: string]: any to Data.Object interface. At present, you receive an error if you attempt to check event.data.object.\<anything\>, as it is strictly typed to an empty object.

@svallory
Copy link

svallory commented Aug 11, 2020

There's a quick workaround for this. Add this to a declaration or any ts file imported in your project:

declare module 'stripe' {
  namespace Stripe {
    interface TypedEventData<T> extends Stripe.Event.Data {
      object: T;
      previous_attributes?: Partial<T>;
    }

    interface TypedEvent<T = any> extends Stripe.Event {
      data: TypedEventData<T>;
      type: Exclude<Stripe.WebhookEndpointCreateParams.EnabledEvent, '*'>;
    }
  }
}

Then use Stripe.TypedEvent<Stripe.Subscription> for example. This could easily be added to Stripe's official typing too.

@kamil-stripe kamil-stripe added the type definition Marks issue related to outdated or incorrect TypeScript type definition label Apr 20, 2022
@saiichihashimoto
Copy link

Strongly related: #1387

@ItsWendell
Copy link

@JamieS1211's solution to this is perfect, would be awesome to see this in de SDK itself!

@Jule-
Copy link

Jule- commented Aug 1, 2022

2 years later still no real out-of-the-box solution for typing? 👀

@JamieS1211 do you have an updated version of your type def file? Thanks a lot! 🙏

@kgajera
Copy link

kgajera commented Aug 27, 2022

In the meantime while we don't have official typings, I published a package that contains the typings: https://github.com/kgajera/stripe-event-types

The typings are generated by scraping Stripe's docs that list the types of events: https://stripe.com/docs/api/events/types

Or if you just want to copy the type declarations, they are here: https://github.com/kgajera/stripe-event-types/blob/main/index.d.ts

@patilanz
Copy link

Any updates from Stripe team about this?

@JefferyHus
Copy link

This does not stop only on casting or using some provided solutions here, it goes deep as well into the expected object type. There are many missing properties from objects, for example the events customer.subscription.* return an object that contains a plan property, but it is not the case for Stripe.Subscription. stripe.webhooks.constructEvent is returning a flat type of Stripe.Event so it is really a nightmare to type it, casting is something I would love to stay away from as much as possible.

@hhsissi
Copy link

hhsissi commented Jul 13, 2023

[> In the meantime, we recommend casting, as in this example: https://github.com/stripe/stripe-node/master/8f3c3ec/examples/webhook-signing/typescript-node-express/express-ts.ts#L58-L60

const charge = event.data.object as Stripe.Charge;

In the future, we hope to type events well enough that checking event.type === 'charge.succeeded' will be enough for TS to infer that event.data.object is a Stripe.Charge.

](#758 (comment))

Referenced link doesn't work anymore, here's an example =>

https://github.com/stripe/stripe-node/blob/master/examples/webhook-signing/express/main.ts#L57

@huw
Copy link

huw commented Oct 16, 2023

I think #1921 solves this issue!

@pakrym-stripe
Copy link
Contributor

This is now available starting with v13.11.0

@hayksaryan
Copy link

For me, event.data.previous_attributes is still typed as Stripe.Event.Data.PreviousAttributes.
I would expect a generic that properly infers Partial<Something> from Stripe.SomethingUpdatedEvent.
Otherwise, I'm forced to do it like this: event.data.previous_attributes as Partial<Stripe.Subscription>

@pakrym-stripe
Copy link
Contributor

Good point, apologies that we missed previous attributes. Filed #1978

@hayksaryan
Copy link

Good point, apologies that we missed previous attributes. Filed #1978

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
future type definition Marks issue related to outdated or incorrect TypeScript type definition
Projects
None yet
Development

No branches or pull requests