Stripe can return 3 different object types from as the customer. I want the customer id which is what is normally returned.
What I have below is pretty ugly.
Is there a better way to do this?
const stripeCustomer: string | Stripe.Customer | Stripe.DeletedCustomer = checkoutSession.customer;
let stripeCustomerId: string;
if (stripeCustomer instanceof Object && "email" in stripeCustomer) {
// customer is of type Stripe.Customer
stripeCustomerId = stripeCustomer.id;
} else if (typeof stripeCustomer === 'string') {
// customer is id
stripeCustomerId = stripeCustomer;
} else {
// customer is of type Stripe.DeletedCustomer
stripeCustomerId = null;
}
CodePudding user response:
You can use a user-defined type guards, which let your plug your own custom type-checking logic into the type system.
When they're true for an object, they inform the flow-sensitive typing that the object has the specified type:
function isStripeCustomer(object: any): object is Stripe.Customer {
return object instanceof Object
&& "object" in object
&& object.object === 'customer'
&& !object.deleted
}
function isStripCustomerID(object: any): object is string {
return typeof object === "string"
}
function isStripeDeletedCustomer(object: any): object is Stripe.DeletedCustomer {
return object instanceof Object
&& "object" in object
&& object.object === 'customer'
&& object.deleted
}
const customer: string | Stripe.Customer | Stripe.DeletedCustomer = checkoutSession.customer;
let stripeCustomerId: string | null
if (isStripeCustomer(customer)) {
stripeCustomerId = customer.id
} else if (isStripCustomerID(customer)) {
stripeCustomerId = customer;
} else if (isStripeDeletedCustomer(customer) {
stripeCustomerId = null;
} else {
// It was none of the known types. Perhaps a new type of result was
// add in a future version of their API?
}
CodePudding user response:
The basic concept you use is the right one. You can enhance it with typeguards to make it type-safe and allow to identify issues at compile-time:
interface Customer {
id: string;
}
type CustomerResponse = Customer | string | null;
function isCustomerObject(customer: CustomerResponse): customer is Customer {
return customer != null && typeof customer === "object" && customer.id != null;
}
function isString(str: CustomerResponse): str is string {
return typeof str === "string";
}
function identify(obj: Customer | string | null) {
if (isCustomerObject(obj)) {
console.log(obj, "is a customer with ID", obj.id);
} else if (isString(obj)) {
console.log(obj, "is a string with value", obj);
} else {
console.log(obj, "is null");
}
}
const customerObject: Customer = {
id: "123"
};
identify(customerObject);
identify("123");
identify(null);