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

TypeScript交叉类型报错原因及单字符串属性类型实现方案

TypeScript类型兼容错误:id属性与索引签名冲突

问题代码

type A<T> = {
  id: string
} & Record<string, T>

const test: A<number> = {
  id: 'dd',
  anyKey: 33
}

错误信息

TS2322: Type { id: string; anyKey: number; } is not assignable to type A<number>
Type { id: string; anyKey: number; } is not assignable to type Record<string, number>
Property id is incompatible with index signature.
Type string is not assignable to type number

错误原因

你定义的A<T>是{id: string}和Record<string, T>的交集类型,这意味着所有属性必须同时满足两个类型的约束:

  • 从{id: string}来看,id属性的类型是string;
  • 从Record<string, T>来看,所有属性(包括id)都必须符合索引签名的类型T。

当你指定A<number>时,id需要同时是string和number——这两种类型没有交集(结果为never类型),因此触发类型不兼容错误。

解决方案

要实现「仅id为string,其余属性为指定类型T」的自定义类型,推荐使用映射类型的键重映射(TypeScript 4.1+支持),通过排除id键来分离约束:

type A<T> = {
  id: string;
} & {
  [K in PropertyKey as Exclude<K, 'id'>]: T;
};

// 测试示例
const test: A<number> = {
  id: 'dd',
  anyKey: 33,
  anotherKey: 44
}; // 类型校验通过

这种写法的核心是Exclude<K, 'id'>,它在映射类型中排除了id键,确保除id外的所有属性必须为T类型,同时保留id为string的独立约束。

如果你的TypeScript版本低于4.1,也可以使用以下(稍宽松)写法:

type A<T> = {
  id: string;
  [key: string]: T | string;
}
// 注意:此写法允许其他属性为string类型,若需严格限制其余属性为T,建议使用映射类型方案

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:27:44