如何利用泛型返回子属性为传入类型的自定义类型?
xp Field in Nested Order Types Got it, let's break down how to solve this. You want API consumers to define the exact type of the xp field for each nested object (Order, User, Address) while keeping the core structure intact. Generics are perfect for this—they let you parameterize the types so users can plug in their own custom shapes for xp.
Step 1: Add Generics to Nested Interfaces
First, update the User and Address interfaces to accept a generic that defines their xp type. We'll set a default of any so existing code that doesn't specify a type still works:
// User with customizable xp type interface User<TUserXp = any> { ID: string; Username: string; xp: TUserXp; } // Address with customizable xp type interface Address<TAddressXp = any> { ID: string; City: string; xp: TAddressXp; }
Step 2: Make the Order Interface Generic
Next, update the Order interface to accept three generics: one for its own xp, one for FromUser.xp, and one for Address.xp. Again, defaults to any for backward compatibility:
interface Order<TOrderXp = any, TUserXp = any, TAddressXp = any> { ID: string; Status: string; FromUser: User<TUserXp>; Address: Address<TAddressXp>; xp: TOrderXp; }
Step 3: How Consumers Use This
Now API users can define custom types for each xp field and pass them into the Order generic. Here's an example:
// Define custom xp shapes for each object type OrderXp = { discount: number; promoCode: string }; type UserXp = { isVIP: boolean; loyaltyPoints: number }; type AddressXp = { isCommercial: boolean; deliveryNotes: string }; // Create a fully customized Order type type CustomizedOrder = Order<OrderXp, UserXp, AddressXp>; // Now accessing fields will have proper type checking: const myOrder: CustomizedOrder = { ID: "123", Status: "shipped", FromUser: { ID: "456", Username: "johndoe", xp: { isVIP: true, loyaltyPoints: 150 } // Type-checked against UserXp }, Address: { ID: "789", City: "New York", xp: { isCommercial: false, deliveryNotes: "Leave at door" } // Type-checked against AddressXp }, xp: { discount: 10, promoCode: "SAVE10" } // Type-checked against OrderXp };
Partial Customization
Users don't have to define all three xp types—they can only customize the ones they care about, and the rest will fall back to any:
// Only customize the Order's xp, leave User and Address xp as any type SemiCustomOrder = Order<{ orderTags: string[] }>;
This approach keeps your SDK flexible, type-safe, and backward-compatible while giving consumers full control over the custom xp data they want to attach to each object.
内容的提问来源于stack exchange,提问作者Crhistian

