47ndr
47ndr

Reputation: 633

Typescript infer "keys of parent" as type

How can I infer the keys of the parent as type of a nested property?


interface List {
    [key:string]: Definition<keyof List>
}

interface Definition<T> {
    [key:string]: Field<T>
}

type Field<T> = FieldA | FieldB<T>;

interface FieldA {
    type: string
}

interface FieldB<T> {
    definition: T 
}

const list:List = {
    def1: {
        field1: {
            type: 'a'
        }
    },
    def2: {
        definition: 'def1'
                    // ~~~ Type 'string' is not assignable to type 'Field<never>'.
    }

}

Here the type of the definition property is never. I would like to be def1 | def2.

Or more in general to get the keys of the parent object and use it as type.

Playground Link

Simpler version

interface List {
    [key:string]:keyof List
}

const list:List = {
    def1: 'def2',
          // ~~~ Type 'string' is not assignable to type 'never'.
    def2: 'def1'
          // ~~~ Type 'string' is not assignable to type 'never'.
}

Why keyof List is of type never? And how can I get the keys considering I don't know them in advance.

Upvotes: 1

Views: 835

Answers (1)

Tomasz Gawel
Tomasz Gawel

Reputation: 8520

This works, although it's ugly ;)

type List<K extends keyof any> = { [key in K]: K };

const list = new class C implements List<keyof C> {
    def1: 'def2'
    def2: 'def1'
    def5: 'def5'
}

That's a bit less ugly and also works ;)

type List<T extends object> = { [key in keyof T]: keyof T }
const List = <O extends object>(o: List<O>): List<O> => o;

const list = List({
    def1: 'def2',
    def2: 'def1',
    def5: 'def5'
});

Upvotes: 1

Related Questions