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

无泛型自引用约束类型:实现值唯一的对象类型

实现非泛型UniqueObject类型:确保对象所有值唯一

我已经实现了一个泛型类型Unique<T>,能够保证对象的所有值唯一。现在需要定义一个非泛型的UniqueObject类型,无需传入泛型参数,直接用于变量声明:当赋值的对象值全唯一时不报错,存在重复值时报错。

现有泛型实现

type Unique<T extends object> = {
  [x in keyof T]: Exclude<keyof T, x> extends infer K ? K extends keyof T ? T[K] extends T[x] ? unknown : never : never : never;
} extends infer G ? G[keyof G] extends never ? T : never : never;

// 测试泛型:值唯一时返回原类型
type AreUnique = Unique<{a: string, b: number}> // {a: string, b: number}
// 值重复时返回never
type NotUnique = Unique<{a: string, b: string}> // never

目标效果

const foo: UniqueObject = {a: 'foo', b: 'bar'} // 无报错,符合要求
const bar: UniqueObject = {a: 'foo', b: 'foo'} // 报错,无法将重复值的对象赋值给never类型

失败尝试及问题

我之前的尝试无法正确推导对象的具体键值对,导致校验失效:

type UniqueObject = {
  [x: string]: object
} extends infer G ? G extends object ? Unique<G> : never : never;

const a: UniqueObject = {
  a: 'foo',
  g: 'bar'
}

这里用{[x: string]: object}作为基础类型过于宽泛,无法让TypeScript正确推断出具体的键值类型,因此Unique<G>无法完成有效的重复值校验。

解决方案

通过infer让TypeScript在赋值时自动推导对象的具体类型,再应用已有的Unique<T>校验逻辑:

type Unique<T extends object> = {
  [x in keyof T]: Exclude<keyof T, x> extends infer K ? K extends keyof T ? T[K] extends T[x] ? unknown : never : never : never;
} extends infer G ? G[keyof G] extends never ? T : never : never;

type UniqueObject = T extends infer U ? U extends object ? Unique<U> : never : never;

测试验证

// 正确:值唯一,无报错
const validObj: UniqueObject = { name: 'Alice', age: 25, isStudent: false };

// 错误:存在重复值,报错提示无法赋值给never
const invalidObj: UniqueObject = { a: 1, b: 1, c: 2 };

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 01:36:08