You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确使用泛型?能否让FormResult提取ControlData的value类型?

Solution: Extracting Control Values with FormResult

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 a ControlData (or a subtype like ButtonSelectControlData), so we can safely access the value property later.
  • FormResult<T extends FormData> uses a mapped type to iterate over every key K in T. For each key, we extract the type of the value property from T[K] (which is a ControlData subtype).

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:01:53