Alireza Mirian
Alireza Mirian

Reputation: 6662

Typescript indexed access in which index is queried from another property of the same interface

An example demonstrates my question better than words:

interface X {
    a: number,
    b: string
}

interface KeyValue<T> {
    key: keyof T,
    value: T[this['key']]
}

const keyValue: KeyValue<X> = {
    key: 'a',
    value: 'Error! this should be a number'
};

I want the type of value to be based on value of key. I mean if key is a, then I need the type of value to be the same as type of X[a], which is number. But currently, the type of value is string | number which is the union type of all value types in X.

Can I achieve this with current typescript features?

Upvotes: 2

Views: 603

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249606

You can't do it directly you need an extra type parameter

interface X {
    a: number,
    b: string
}

interface KeyValue<T, K extends keyof T> {
    key: K,
    value: T[this['key']] // or T[K]
}

const keyValue: KeyValue<X, 'a'> = {
    key: 'a',
    value: 0
};

To avoid typing the name of the property twice you can use a function to help with the creation. You need a fi function that returns a function as Typescript does not allow partial type argument inference yet

function newY<T>() {
    return function <K extends keyof T>(p: Y<T, K>) {
        return p;
    }
}

let xx = newY<X>()({ key: 'a', value:0})

Upvotes: 1

Related Questions