如何强制TypeScript接口动态字段名等于type字段的值?
type property value in TypeScript? Great question! This is totally achievable in TypeScript—you just can’t do it with a basic interface like your original one. Instead, we’ll use generics to create a tight, type-safe link between the type property and the required dynamic key. Let’s walk through how this works.
The Solution: Generic Type with Constraints
Instead of a plain interface, define a generic type where we capture the exact string value of type as a type parameter. This lets us enforce that the dynamic key must match that exact value:
type DashboardRequest<T extends string> = { name: string; type: T; } & { [K in T]: any };
How This Works
- The generic
Tis constrained to be a string (sincetypeis a string property). - The first object defines the mandatory
nameandtypeproperties, wheretypeis explicitly set to the genericT. - The
&(intersection type) combines that with an index type{ [K in T]: any }, which requires exactly one key matching the value ofT(i.e., the value oftype).
Using the Type
TypeScript will automatically infer the generic parameter from the type property, so you don’t even need to specify it manually most of the time:
// Valid: `type` is "bar", so we have a "bar" key const validRequest: DashboardRequest = { name: 'foo', type: 'bar', bar: 5 }; // You can also explicitly specify the generic if you want const userRequest: DashboardRequest<'user'> = { name: 'baz', type: 'user', user: { id: 123 } };
What Happens When It’s Invalid?
TypeScript will throw errors if the key doesn’t match type, or if the key is missing entirely—exactly what you want:
// ❌ Error: Property "bar" is missing const missingKey: DashboardRequest = { name: 'foo', type: 'bar' }; // ❌ Error: Object literal may only specify known properties, and "baz" does not exist in type... const wrongKey: DashboardRequest = { name: 'foo', type: 'bar', baz: 5 };
Allowing Extra Optional Keys (If Needed)
If you want to permit additional dynamic keys beyond the one matching type, you can extend the type with a broader index signature:
type DashboardRequest<T extends string> = { name: string; type: T; [K in T]: any; } & { [key: string]: any };
Now you can add extra keys, but you’ll still be required to include the one that matches type.
Wrap-Up
This generic approach gives you the compile-time safety you’re looking for—ensuring the dynamic key always aligns with the type property value. It’s a clean, TypeScript-native way to enforce this kind of relationship between properties.
内容的提问来源于stack exchange,提问作者mindparse

