简体   繁体   中英

TypeScript: Type of Key of Object?

I'd like to define the following types:

type Item = {
    name: string,
    value: number | string
}


type ItemFilter<T extends Item> = {
    property: keyof Item;
    value: // ?????? I'd like to have here the type of Item[property]
}

How can I set value to have the type of item's property property?

I'd like to do the following:

const myItem: NumberItem = {
    name: 'phoneNumber',
    value: 1111111,
}

const valueFilter: ItemFilter<NumberItem> = {
    property: 'value',
    value: 11111, // SHOULD BE OK
}


const valueFilter: ItemFilter<NumberItem> = {
    property: 'value',
    value: 'STRING', // SHOULD FAIL
}

What I would do here is value constructor which would generate our proper filter value for our object. Consider the code:

const makeFilter = <T extends Record<string, any>> (item: T) => <K extends keyof T>(property: K, value: T[K]) => {
    return {
        property,
        value
    }
}

// TESTS
const myItem = {
    name: 'phoneNumber',
    value: 1111111,
}

const filter = makeFilter(myItem) // create function for specific object filtering

filter('value', 1231)  // ok
filter('value', 'a') // error as expected
filter('name', 1231)  // erorr as expected
filter('name', 'fine') // ok

Pay attention that we don't even need any Item type anymore, solution will work with every object.

Some explanation:

  • makeFilter is a function which derives types by arguments
  • it firstly get our initial object and return function which has arguments only for this specific object type
  • filter = makeFilter(obj) creates our needed filter constructor for specific object
  • using filter after has already proper narrowed types in the arguments
  • property: K, value: T[K] means that value needs to be value of the object under the key - K

Why I have used function and not type directly.

Function allows us for type inference over arguments, so we don't need to repeat redundantly types. We just make filter for wanted object.

playground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM