Home > OS >  Get type of generic's value by key declared on a property in Typescript interface and use it as
Get type of generic's value by key declared on a property in Typescript interface and use it as

Time:08-27

I want to add a function signature on a typescript interface which one of its parameters will have a type based on the declared key's value.

I've tried the approach bellow but it doesn't work, as the value's type is every possible type from T. Instead, I want the value of the declared key

so if key "num" is a number, I want the "value" parameter in function to be a number


type RowType = Record<string, any>

interface Row<T = RowType, K extends keyof T = keyof T> {
    key: K
    render: (value: T[K], row: T) => any
}

interface DumpRecord = {
    arr: string[], 
    num: number, 
    str: string
}

let row: Row<DumpRecord> = {
 key: 'arr',
 render: (value, row) => ... // value should be array, row should be DumpRecord
}

// or

let row: Row<DumpRecord> = {
 key: 'num',
 render: (value, row) => ... // value should be number
}


CodePudding user response:

You need to use discriminated unions here:

type RowType = Record<string, any>

interface Row<T = RowType, K extends keyof T = keyof T> {
    key: K
    render: (value: T[K], row: T) => any
}

interface DumpRecord {
    arr: string[],
    num: number,
    str: string
}
type Values<T> = T[keyof T]

type Union = Values<{
    [Prop in keyof DumpRecord]: Row<DumpRecord, Prop>
}>

const one: Union = {
    key: 'arr',
    render: (value, row) => {
        value // string[]

    }
}

const two: Union = {
    key: 'num',
    render: (value, row) => {
        value // number
    }
}

Playground

You can find more examples in this question and my article

  • Related