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

如何为TypeScript函数添加类型约束,确保两属性键类型一致

解决TypeScript中assign函数的类型兼容限制问题

你需要让assign函数仅允许属性值可相互赋值的键组合,核心是要在泛型中关联两个键对应的属性类型,之前的写法因为没有正确绑定泛型参数的关系,所以无法生效。

正确的实现方案

通过将两个键名K1、K2作为独立的泛型参数,结合条件类型筛选出符合赋值兼容要求的K2,就能实现类型约束:

function assign<T1, K1 extends keyof T1, T2, K2 extends keyof T2>(
  o1: T1,
  k1: K1,
  o2: T2,
  k2: K2 extends unknown ? (T2[K2] extends T1[K1] ? K2 : never) : never
) {
  // 这里的类型断言是安全的,因为参数层面已经做了类型兼容检查
  o1[k1] = o2[k2] as T1[K1];
}

验证效果

用你给出的示例测试:

let a = { foo: 'hello', version: 10 };
let b = { bar: 'bye' };

assign(a, 'foo', b, 'bar'); // 正常通过,两者均为string类型
assign(a, 'version', b, 'bar'); // 触发类型错误,number与string类型不兼容

原理说明

  1. 将K1和K2设为泛型参数,TypeScript可以精准追踪它们对应的属性类型T1[K1]和T2[K2]
  2. 利用条件类型T2[K2] extends T1[K1] ? K2 : never,只允许o2[k2]的类型可以赋值给o1[k1]的键名作为k2的有效值
  3. 函数内部的as T1[K1]断言是因为TypeScript的类型推导在某些场景下无法自动识别兼容性,但参数层面已经做了严格检查,所以不会有类型安全问题

另一种简洁写法

你也可以通过映射类型先筛选出T2中符合条件的键,再提取这些键的联合类型作为k2的类型,效果一致:

function assign<T1, T2, K1 extends keyof T1>(
  o1: T1,
  k1: K1,
  o2: T2,
  k2: { [K in keyof T2]: T2[K] extends T1[K1] ? K : never }[keyof T2]
) {
  o1[k1] = o2[k2] as T1[K1];
}

内容的提问来源于stack exchange,提问作者John T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:20:23