Reputation: 8136
I have a bunch of data that's built into an object literal. The keys of this object also exist in each of the child objects in this object and I'd like to enforce that with typescript:
type People = {[NAME in string]: { name: NAME; age: number }};
const people: People = {
Jeff: { name: "Jeff", age: 30 },
Fred: { name: "Freddy", age: 25 }, // no error, name evaluates to string
Sally: { name: "Sally", age: 35 },
};
In the past I've done similar things using string unions:
type People = {[NAME in "Jeff" | "Fred" | "Sally"]: { name: NAME; age: number }};
const people: People = {
Jeff: { name: "Jeff", age: 30 },
Fred: { name: "Freddy", age: 25 }, // ERROR: Type '"Freddy"' is not assignable to type '"Fred"'. ts(2322)
Sally: { name: "Sally", age: 35 },
};
But for my current use case maintaining a separate union type in addition to the object would be excessive.
Is it possible to use the key type from an indexed object in the children of that object?
Upvotes: 0
Views: 71
Reputation: 10525
Best I can do is like this:
type People<T> = { [K in keyof T]: { name: K; age: number } };
function createPeople<T extends People<T>>(people: T): People<T> {
return people;
}
const people = createPeople({
Jeff: { name: 'Jeff', age: 30 },
Fred: { name: 'Freddy', age: 25 }, // ERROR: Type '"Freddy"' is not assignable to type '"Fred"'. ts(2322)
Sally: { name: 'Sally', age: 35 },
});
Upvotes: 1