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

如何在TypeScript泛型中强制字段类型与另一字段一致?

类型一致性约束的高效实现方案

场景1:强制master与slave值类型严格匹配

给定以下代码,需要实现MyType,确保slave的类型与master完全一致:

type MyStr = "one" | "two" | "three";

const x: MyType<MyStr> = { master: "one", slave: "one" }; // 应编译通过
const y: MyType<MyStr> = { master: "one", slave: "two" }; // 应编译失败

原方案的问题

原方案通过映射类型生成所有可能的键值组合,再通过索引获取最终类型:

type MyType<T extends string> = {
  [K in T]: { master: K, slave: K }
}[T];

该方案虽能满足需求,但当T包含大量成员时,会生成庞大的中间映射类型,导致TypeScript服务过载崩溃。

优化方案

利用TypeScript联合类型的条件类型分发特性,无需预生成所有映射组合,直接推导每个成员对应的约束类型:

type MyType<T extends string> = T extends infer K ? { master: K; slave: K } : never;

当T为联合类型时,条件类型会自动对每个成员进行处理,最终返回所有符合约束的类型联合,性能远优于原方案。


场景2:ElementFieldType的类型一致性约束

实际需求中,需要确保name指定的键与Element组件的value/onChange参数类型严格匹配:

type ElementFieldType<T, K extends keyof T> = {
  name: K;
  Element: FC<{ value: T[K], onChange: (value: T[K]) => void }>;
}

优化方案

同样利用条件类型分发特性,避免生成中间映射对象,提升性能:

import { FC } from 'react';

type ElementFieldType<T> = keyof T extends infer K ? 
  K extends keyof T ? {
    name: K;
    Element: FC<{ value: T[K], onChange: (value: T[K]) => void }>;
  } : never : never;

使用时无需显式指定K,TypeScript会自动推导name对应的类型,并约束Element的props类型:

type FormData = { username: string; age: number };

// 编译通过:name与Element类型匹配
const validField: ElementFieldType<FormData> = {
  name: 'username',
  Element: ({ value, onChange }) => <input value={value} onChange={(e) => onChange(e.target.value)} />
};

// 编译失败:name为age,但Element处理的是string类型
const invalidField: ElementFieldType<FormData> = {
  name: 'age',
  Element: ({ value, onChange }) => <input value={value} onChange={(e) => onChange(e.target.value)} />
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:46:30