无泛型自引用约束类型:实现值唯一的对象类型
实现非泛型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
相关产品推荐
相关产品推荐

