首页 > 解决方案 > TypeScript:对象键的类型?

问题描述

我想定义以下类型:

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]
}

如何设置value具有项目属性的类型?

我想做以下事情:

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
}

标签: typescript

解决方案


我在这里要做的是值构造函数,它将为我们的对象生成正确的过滤器值。考虑代码:

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

请注意,我们甚至Item不再需要任何类型,解决方案将适用于每个对象。

一些解释:

  • makeFilter是一个通过参数派生类型的函数
  • 它首先获取我们的初始对象并返回函数,该函数仅具有此特定对象类型的参数
  • filter = makeFilter(obj)为特定对象创建我们需要的过滤器构造函数
  • 在参数中使用filterafter 已经有适当的缩小类型
  • property: K, value: T[K]意味着 value 需要是 key 下对象的 value -K

为什么我使用函数而不是直接输入。

函数允许我们对参数进行类型推断,因此我们不需要重复冗余类型。我们只是为想要的对象制作过滤器。

操场


推荐阅读