I'm creating website that uses code generation for type safety around GraphQl queries. Some components in my app get part of object as prop. The type looks as follows:
type ActiveOrderQuery = {
__typename?: "Query" | undefined;
activeOrder?: {
__typename?: "Order" | undefined;
id: string;
subTotalWithTax: number;
subTotal: number;
currencyCode: CurrencyCode;
lines: Array<{
__typename?: 'OrderLine';
id: string;
quantity: number;
linePrice: number;
linePriceWithTax: number;
unitPrice: number;
unitPriceWithTax: number;
productVariant: {
__typename?: 'ProductVariant';
name: string;
featuredAsset?: {
__typename?: 'Asset';
preview: string;
} | null;
};
discounts: Array<{
__typename?: 'Discount';
type: AdjustmentType;
description: string;
amount: number;
amountWithTax: number;
}>;
}>;
} | null | undefined;
}
My components maps over 'lines' property so I'd like to dynamically create or access type definition for ActiveOrderQuery["activeOrder"]["lines"].
I've tried mapped types but those only allow me to go one level deep so I could do
type NestedType = ActiveOrderQuery["activeOrder"]
but not
type NestedType = ActiveOrderQuery["activeOrder"]["lines"]
Is there any solution to that problem? I'd like to avoid writing those types by hand as they can change due to code generation.
CodePudding user response:
This took longer to figure out than I would like to admit haha.
The problem is that activeOrder
can be either an object, null or undefined, of course the keys of null and undefined are never
so you can't extract them.
To get the keys out, first get rid of null|undefined
using the Exclude
utility.
type NestedA = Exclude<ActiveOrderQuery["activeOrder"], null|undefined>;
type NestedB = NestedA["lines"];
type Nested = Exclude<ActiveOrderQuery["activeOrder"], null|undefined>["lines"];