I'm trying to make a Record of this shape where the id
property equals the key of each object entry:
{
id_1: {
id: 'id_1',
date: 1234
comment: 'blah'
},
id_2: {
id: 'id_2',
date: 5678,
comment: 'boo'
}
}
Here's what I've come up with so far:
export type TMap<T extends string> = {
[P in T]: { _id: P; date: number; comment: string };
};
However, when I use it I need to pass in a paremeter like this:
const myMap: TMap<string> = {...}
Is the a simpler way to achieve a record where the key is equal to one of the value's properties?
CodePudding user response:
I'm not sure if it's possible to get the compiler to infer what you want using just an annotation without generics, but you could use a functional approach:
function validMap <T extends {
[K in keyof T]: K extends string ? {
id: K;
date: number;
comment: string;
} : never;
}> (value: T): T {
return value;
}
const map1 = validMap({
a: {
id: 'a',
date: 1,
comment: 'hello',
},
b: {
id: 'b',
date: 2,
comment: 'world',
},
});
const map2 = validMap({
a: {
id: 'a',
date: 1,
comment: 'hello',
},
b: {
id: 'a',
// ^^
// Type '"a"' is not assignable to type '"b"'.(2322)
date: 1,
comment: 'hello',
},
});
CodePudding user response:
You could specify string as the default type of your TMap
:
export type TMap<T extends string = string> = {
[P in T]: { id: P; date: number; comment: string };
};
Then you could use it like so:
const myMap: TMap = { ... }