Sandy Gifford
Sandy Gifford

Reputation: 8136

Use type from index in child types

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

Answers (1)

Mike Jerred
Mike Jerred

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

Related Questions