网站搜索

TypeScript 将枚举转换为对象类型的最佳实践


假设我们有一个像这样的枚举,

enum CustomerType {
   New = 'new',
   Owner = 'self',
   Loyal = 'subscriber'
}

使用这个可以更容易地添加检查,例如

if(customer.type === CustomerType.New)

对于使用枚举值作为键来为对象打类型,最佳做法是什么?在这种情况下,假设我们有一个名为 getCustomerType 的方法,它会返回

{ 
   new: true,
   self: false,
   subscriber: false
}

另外,请注意,由于设计原因,将其简化为仅返回真实键可能不可行 :)

到目前为止我尝试的是类似的东西

type CustomerConfig = { [key in CustomerType]: boolean }

现在假设我想从这个对象中获取第一个键,也就是 true,我会这样做。

export const getCustomer = (obj: CustomerConfig): CustomerType => {
    const customerType = Object.keys(obj).find(x => {
        // Object.keys return `string[]` instead of keyof type https://github.com/microsoft/TypeScript/issues/20853
        return obj[x as keyof CustomerConfig]
    })
    return customerType as CustomerType
}

const tempCustomer = getCustomer({
    'new': true,
    'self': false,
    'subscriber': false
})

console.log(tempCustomer === CustomerType.New)  // true
console.log(tempCustomer === CustomerType.Owner) //false

有没有更好的方法来做这件事?

答案#1

我建议,你可以做一些改进:

  • 数组的 find 函数在找不到匹配项的情况下可能返回 undefined,所以最好也添加这个类型并进行一些额外的检查
  • 正如你所说,TypeScript 对 Object.keys 返回了错误的类型,所以你可以直接告诉 TypeScript 正确的类型
export const getCustomer = (obj: CustomerConfig): CustomerType | undefined => {
  return (Object.keys(obj) as Array<keyof CustomerConfig>)
     .find(x => obj[x])
}

const tempCustomer = getCustomer({
    'new': true,
    'self': false,
    'subscriber': false
})