如何在TypeScript中为对象的指定键(payload)指定类型?
Great question! You can easily enforce the payload property to match your PayloadTypes union without having to define every other key in your action objects. Here are a couple of straightforward approaches:
First, let's recap your existing type
type PayloadTypes = "VIEW_OFFER_DETAILS" | "ADD_TO_CART" | "MORE_INFO_ITEM" | "SHOW_ITEM_LOCATION";
Approach 1: Use an intersection type for maximum flexibility
This method lets your action objects have any additional keys (with any values) while strictly enforcing the payload to be one of your union values:
// Define a type that requires payload to be PayloadTypes, plus any other properties type Action = { payload: PayloadTypes; } & Record<string, unknown>; // Now use this type for your actions array const actions: Action[] = [ { type: "postback", text: "View details", payload: "VIEW_OFFER_DETAILS", // ✅ Valid (matches PayloadTypes) metadata: { userId: 123, offer: JSON.stringify({ id: 456 }) } }, { type: "quick_reply", text: "Show location", payload: "SHOW_ITEM_LOCATION", // ✅ Valid randomExtraKey: "whatever you want" // ✅ Allowed (no need to define it upfront) } ];
Why this works:
{ payload: PayloadTypes }ensures thepayloadkey is present and uses your union type.& Record<string, unknown>adds support for any other keys with values typed asunknown(safer thananybecause it requires type checking before using those values).
Approach 2: Explicitly define known keys (if you want more control)
If you know some of the other keys that will be present (like type, text, metadata), you can define them explicitly while still allowing arbitrary extra keys:
type Action = { payload: PayloadTypes; type: string; // Required string type for 'type' text: string; // Required string type for 'text' metadata?: Record<string, unknown>; // Optional metadata object } & Record<string, unknown>; // Still allows unforeseen extra keys
This gives you more control over the types of known properties while keeping flexibility for unexpected keys.
Type safety in action
TypeScript will automatically catch invalid payload values:
// ❌ This will throw an error: "INVALID_PAYLOAD" isn't in PayloadTypes const badAction: Action = { type: "postback", text: "Oops", payload: "INVALID_PAYLOAD" };
内容的提问来源于stack exchange,提问作者Johhan Santana

