question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Property 'metadata' does not exist on type 'Object'

See original GitHub issue

Using the latest API version, and writing my code in Typescript, when trying to get the metadata object inside data.object, I get this error in my IDE, stopping TypeScript form compiling:

Property ‘metadata’ does not exist on type ‘Object’

metadata is 100% in the data.object object, so not sure why it’s not including in the types?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
robert-nashcommented, Jul 29, 2022

I am not a TypeScript expert but I do wonder if, whilst this is how the library is designed at the moment, it is something which could possibly be improved. It seems that improving the typings in some way (perhaps with discriminated unions) might make this a bit more user friendly and reduce the times when it is necessary to manually cast the object which seems to introduce the possibility for incorrectly casting when it might be possible to let TypeScript manage this by itself.

0reactions
robert-nashcommented, Jul 29, 2022

I just wanted to confirm that there was a modicum of basis to what I was saying so I attempted to modify the types I am making use of to see if it was possible. I made a small modification to types/2020-08-27/Events.d.ts implementing a base “EventBase” interface which has all of the common properties and then two example event interfaces “PaymentIntentEvent” and “SubscriptionEvent” which extend “EventBase” but have a union of possible values for the type and specific types for data.object. This means that a simple switch on event.type allows TypeScript to correctly (in this very contrived example) infer the type of object.

I understand that actually implementing this may not be at all simple and I don’t know if the way you are currently generating the types from OpenAPI even allows this but I think it is fair to say that this is at least an opportunity for improvement in the library since it seems that TypeScript is capable of representing the way the API works more accurately

Here is my example Events.d.ts (obviously I understand that this is not at all how you would implement this but is just a minimum example which I think shows that it is possible to achieve this).

// File generated from our OpenAPI spec

import Stripe from "stripe";

interface EventBase {
  /**
   * Unique identifier for the object.
   */
  id: string;

  /**
   * String representing the object's type. Objects of the same type share the same value.
   */
  object: 'event';

  /**
   * The connected account that originated the event.
   */
  account?: string;

  /**
   * The Stripe API version used to render `data`. *Note: This property is populated only for events on or after October 31, 2014*.
   */
  api_version: string | null;

  /**
   * Time at which the object was created. Measured in seconds since the Unix epoch.
   */
  created: number;

  data: Event.Data;

  /**
   * Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode.
   */
  livemode: boolean;

  /**
   * Number of webhooks that have yet to be successfully delivered (i.e., to return a 20x response) to the URLs you've specified.
   */
  pending_webhooks: number;

  /**
   * Information on the API request that instigated the event.
   */
  request: Event.Request | null;

  /**
   * Description of the event (e.g., `invoice.created` or `charge.refunded`).
   */
  type: string;
}

interface PaymentIntentEvent extends EventBase {
  type: "payment_intent.succeeded" |"payment_intent.amount_capturable_updated";
  data: {
    object:Stripe.PaymentIntent;
    previous_attributes: Data.PreviousAttributes
  }
}

interface SubscriptionEvent extends EventBase {
  type: "customer.subscription.updated" |"customer.subscription.trial_will_end";
  data: {
    object:Stripe.PaymentIntent;
    previous_attributes: Data.PreviousAttributes
  }
}

declare module 'stripe' {
  namespace Stripe {
    /**
     * The Event object.
     */
    type Event = PaymentIntentEvent | SubscriptionEvent

    namespace Event {
      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;
      }

      namespace Data {
        interface Object {}

        interface PreviousAttributes {}
      }

      interface Request {
        /**
         * ID of the API request that caused the event. If null, the event was automatic (e.g., Stripe's automatic subscription handling). Request logs are available in the [dashboard](https://dashboard.stripe.com/logs), but currently not in the API.
         */
        id: string | null;

        /**
         * The idempotency key transmitted during the request, if any. *Note: This property is populated only for events on or after May 23, 2017*.
         */
        idempotency_key: string | null;
      }
    }

    interface EventRetrieveParams {
      /**
       * Specifies which fields in the response should be expanded.
       */
      expand?: Array<string>;
    }

    interface EventListParams extends PaginationParams {
      created?: Stripe.RangeQueryParam | number;

      /**
       * Filter events by whether all webhooks were successfully delivered. If false, events which are still pending or have failed all delivery attempts to a webhook endpoint will be returned.
       */
      delivery_success?: boolean;

      /**
       * Specifies which fields in the response should be expanded.
       */
      expand?: Array<string>;

      /**
       * A string containing a specific event name, or group of events using * as a wildcard. The list will be filtered to include only events with a matching event property.
       */
      type?: string;

      /**
       * An array of up to 20 strings containing specific event names. The list will be filtered to include only events with a matching event property. You may pass either `type` or `types`, but not both.
       */
      types?: Array<string>;
    }

    class EventsResource {
      /**
       * Retrieves the details of an event. Supply the unique identifier of the event, which you might have received in a webhook.
       */
      retrieve(
        id: string,
        params?: EventRetrieveParams,
        options?: RequestOptions
      ): Promise<Stripe.Response<Stripe.Event>>;
      retrieve(
        id: string,
        options?: RequestOptions
      ): Promise<Stripe.Response<Stripe.Event>>;

      /**
       * List events, going back up to 30 days. Each event data is rendered according to Stripe API version at its creation time, specified in [event object](https://stripe.com/docs/api/events/object) api_version attribute (not according to your current Stripe API version or Stripe-Version header).
       */
      list(
        params?: EventListParams,
        options?: RequestOptions
      ): ApiListPromise<Stripe.Event>;
      list(options?: RequestOptions): ApiListPromise<Stripe.Event>;
    }
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Typescript : Property does not exist on type 'object'
I am using JSforce and trying to use "search" function on the object but it is throwing "Property 'search' does not exist on...
Read more >
Fix - Property does not exist on type '{}' in TypeScript
To fix the error “Property does not exist on type '{}'” in Typescript and when working with node, remember to access only object...
Read more >
The property '__metadata' does not exist on type 'SP.Group ...
The property '__metadata' does not exist on type 'SP.Group'. Make sure to only use property names that are defined by the type.
Read more >
[Solved]-Property 'x' does not exist on type - appsloveworld
The error is telling you that the type it's inferred for userCredential does have a user property with a metadata property, but the...
Read more >
Documentation - Decorators - TypeScript
and so the new property `reportingURL` is not known. // to the type system: bug . reportingURL ;. Property 'reportingURL' does not exist...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found