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

TypeScript中如何将类型泛型扩展至函数?能否实现无复制粘贴的泛型复用?

Reusing Generic Constraints Without Duplication in TypeScript

Great question! Duplicating generic constraints is a common annoyance in TypeScript, but there are clean ways to reuse them without copying code. Let’s walk through two reliable approaches for your scenario.

Approach 1: Extract Constraints & Defaults into Shared Types

The most straightforward method is to pull the generic constraints and default values into separate top-level type aliases. This lets both your T type and func function reference the same definitions—so you only ever need to update them in one place:

// Step 1: Define shared constraints and defaults once
type TFormTypeConstraint = 'edit' | 'create';
type TRecordTypeConstraint = Record;
type TFormTypeDefault = 'create';
type TRecordTypeDefault = Record;

// Step 2: Reuse them in your type T
type T<
  FormType extends TFormTypeConstraint = TFormTypeDefault,
  RecordType extends TRecordTypeConstraint = TRecordTypeDefault
> = { 
  type: FormType, 
  record: RecordType 
};

// Step 3: Reuse the same constraints/defaults in your function
const func = <
  FormType extends TFormTypeConstraint = TFormTypeDefault,
  RecordType extends TRecordTypeConstraint = TRecordTypeDefault
>(props: T<FormType, RecordType>) => {
  // Your function logic here
};

This approach is highly readable and scales well if you need to reuse these constraints across other parts of your codebase.

Approach 2: Extract Generic Params from Type T Using infer

If you prefer to keep everything tightly coupled to your original T type, you can use TypeScript’s infer keyword to extract its generic constraints and defaults directly:

// Keep your original type T definition
type T<FormType extends 'edit' | 'create' = 'create', RecordType extends Record = Record> = { 
  type: FormType, 
  record: RecordType 
};

// Create a utility type to pull T's generic details
type ExtractTGenerics = T extends T<infer F, infer R> 
  ? { 
      FormType: F extends 'edit' | 'create' ? F : never;
      RecordType: R extends Record ? R : never;
      DefaultFormType: 'create';
      DefaultRecordType: Record;
    } 
  : never;

// Reuse the extracted details in your function
const func = <
  FormType extends ExtractTGenerics['FormType'] = ExtractTGenerics['DefaultFormType'],
  RecordType extends ExtractTGenerics['RecordType'] = ExtractTGenerics['DefaultRecordType']
>(props: T<FormType, RecordType>) => {
  // Your function logic here
};

With this method, any updates to T’s constraints or defaults will automatically propagate to the function—no manual changes needed.

Can We Achieve Generic Reuse Without Copy-Pasting?

Absolutely! Both approaches above eliminate duplicate code entirely. The first is better for maintainability when constraints might be reused across multiple types/functions, while the second is ideal if you want all definitions tied directly to T.

内容的提问来源于stack exchange,提问作者Oki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 15:53:14