如何正确使用泛型?能否让FormResult提取ControlData的value类型?
Absolutely, you can adjust your FormResult type to directly return the inner value types from each control instead of the full ControlData interfaces. Here's how to do it properly with TypeScript generics:
Step 1: Adjust the FormResult Mapped Type
Instead of just copying the control types, we'll extract the value property from each control using a mapped type:
export interface FormData<T extends ControlData = any> { [type: string]: T; } export interface ControlData<T = any> { value: T; } export interface ButtonSelectControlData<T> extends ControlData<T> { query: string; } // Updated FormResult to extract the value type from each control export type FormResult<T extends FormData> = { [K in keyof T]: T[K]['value']; }; // Your existing form data interface remains the same export interface RoutesAddCityData extends FormData { cityId: ButtonSelectControlData<number>; routeId: ControlData<number>; }
Step 2: Verify the Result
Now when you use FormResult<RoutesAddCityData> as a parameter type:
const handleSubmit = (data: FormResult<RoutesAddCityData>) => { // data.cityId is now type number // data.routeId is now type number console.log(data.cityId.toFixed(0)); // Works perfectly! };
How the Generics Work Here
Let's break down the key parts:
FormData<T extends ControlData>ensures every property in the form is aControlData(or a subtype likeButtonSelectControlData), so we can safely access thevalueproperty later.FormResult<T extends FormData>uses a mapped type to iterate over every keyKinT. For each key, we extract the type of thevalueproperty fromT[K](which is aControlDatasubtype).
Alternative: Using infer for Explicit Value Extraction
If you want a more reusable way to extract control values (say for other use cases), you can create a helper type with conditional typing and infer:
type ExtractControlValue<C extends ControlData> = C extends ControlData<infer V> ? V : never; export type FormResult<T extends FormData> = { [K in keyof T]: ExtractControlValue<T[K]>; };
This achieves the same result but makes the value extraction logic explicit and reusable elsewhere in your code.
内容的提问来源于stack exchange,提问作者Sergei Krivochenko

