I have some data in my code like below:
interface Product {
id: number
name: string;
}
enum EnumValue {
'VALUE1' = 'VALUE1',
'VALUE2' = 'VALUE2',
'VALUE3' = 'VALUE3',
}
const data = {
'VALUE1': {
num1: {id: 1, name: '2'},
num2: {id: 2, name: '2'},
},
'VALUE2': {
num1: {id: 1, name: '2'},
},
'VALUE3': {
num1: {id: 1, name: '2'},
},
} as const satisfies { readonly [key in EnumValue]: { [key: string]: Product} };
I need to define a validator for my data type so that it only requires unique identifiers for each EnumValue property. I mean
data = {
'VALUE1': {
num1: {id: 1, name: '2'},
num2: {id: 1, name: '2'},
},
'VALUE2': {
num1: {id: 1, name: '2'},
},
'VALUE3': {
num1: {id: 1, name: '2'},
},
}
ts should throw an error because VALUE1 has 2 objects with id = 1 but
data = {
'VALUE1': {
num1: {id: 1, name: '2'},
num2: {id: 2, name: '2'},
},
'VALUE2': {
num1: {id: 1, name: '2'},
},
'VALUE3': {
num1: {id: 1, name: '2'},
},
is a valid value. I need as const satisfies part to use the data model type in my code. So can you help me define a validator to correct my data type?
There is code to validate unique identifiers over a variety of objects that may help, but the problem is that I don't know how to access the values of the objects to iterate through type validation. link to this question
interface IProduct<Id extends number> {
id: Id
name: string;
}
type Validation<
Products extends IProduct<number>[],
Accumulator extends IProduct<number>[] = []>
=
(Products extends []
// #1 Last call
? Accumulator
// #2 All calls but last
: (Products extends [infer Head, ...infer Tail]
? (Head extends IProduct<number>
// #3 Check whether [id] property already exists in our accumulator
? (Head['id'] extends Accumulator[number]['id']
? (Tail extends IProduct<number>[]
// #4 [id] property is a duplicate, hence we need to replace it with [never] in order to trigger the error
? Validation<Tail, [...Accumulator, { id: never, name: Head['name'] }]>
: 1)
// #5 [id] is not a duplicate, hence we can add to our accumulator whole product
: (Tail extends IProduct<number>[]
? Validation<Tail, [...Accumulator, Head]>
: 2)
)
: 3)
: Products)
)