我有一个可能会变大的数据记录。我想知道是否可以强制记录的键与内部名称值相同?
interface Person<T> {
name: T
title: string
description: string
}
type People = Record<string, Person<string>>
// example data
const data: People = {
sarah: {
name: 'sarah',
title: 'Sarah',
description: 'Hello',
}
}
const badData: People = {
adam: {
name: 'john', // This would cause a typescript error ideally.
...
}
}
我尝试使用通用设置 People,但它需要我将所有键添加到我宁愿避免的联合类型中。 keyof
不起作用,因为在需要 keyof
的地方 undefined object 。
type People<T> = Record<T, Person<T>>
const people: People<keyof typeof people> = {} // Block-scoped variable 'people' used before its declaration.ts(2448)
最佳答案
为了做到这一点,您需要使用额外的函数。
interface Person<T> {
name: T
title: string
description: string
}
type People = Record<string, Person<string>>
type Validate<T extends People> = {
[Name in keyof T]: Name extends T[Name]['name'] ? T[Name] : T[Name] & { name: never }
}
const validator = <
Name extends string,
Human extends Person<Name>,
Data extends Record<Name, Human>
>(data: Validate<Data>) => data
const result = validator({
sarah: {
name: 'sarah',
title: 'Sarah',
description: 'Hello',
},
adam: {
name: 'john', // Error.
title: 'Sarah',
description: 'Hello',
}
})
Validate
迭代每个对象 key
/Name
并检查顶级名称是否相等对象[名称]['名称']
。如果是 - 返回相同的嵌套对象。如果没有 - 返回相同的嵌套对象,但具有 iverriden name
proeprty never
。
因此,您在应该修复的地方遇到了错误。
如果您对函数参数的类型推断感兴趣,您可以查看我的 article
来自@Konrad Madej的验证
的更通用版本:
type Validate<Data extends People> = {
[Name in keyof Data]: Name extends Data[Name]['name'] ? Data[Name] : Omit<Data[Name], 'name'> & { name: Name }
}
如果您有数字键,请考虑以下示例:
interface PayloadObj<T> {
elementId: T;
values: any;
}
type Payload = Record<number, PayloadObj<number>>;
type Validate<T extends Payload> = {
[Key in keyof T]: T[Key] & { elementId: Key }
};
const validator = <
ElementId extends number,
PayloadValue extends PayloadObj<ElementId>,
Data extends Record<ElementId, PayloadValue>
>(data: Validate<Data> & Data): Payload => data;
const result = validator({
0: {
elementId: 0,
values: 'Hello',
},
1: {
elementId: 2, // Error.
values: 'World',
},
});
关于Typescript:是否可以确保键和内部值是相同的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69417437/