如何键入属性和值均来自其他类型的对象

时间:2019-11-15 18:40:30

标签: typescript

我想输入一个对象,其中属性值是仅允许为某种类型的数组,而其属性也仅允许为某种类型(联合类型)。我在下面尝试了两种不同的方法。带有Record的一种,它不允许我区分蔬菜和水果类型。还有不允许我将属性名称限制为某种类型的接口。

img of code

type Veg = 'corn' | 'broccoli' | 'onion' | 'pumpkin' | 'squash' | 'kale';
type Fruit = 'banana' | 'apple' | 'orange' | 'pineapple' | 'passionfruit';
type AllowedFood =  Veg | Fruit;
type AllowedFoodGroups = 'veg' | 'fruit';

// allows me to put the wrong food type (a fruit) in veg (the orange)
const DietShoppingList: Record<AllowedFoodGroups, AllowedFood[]> = {
    veg: ['corn', 'onion', 'orange'],
    fruit: ['banana']
}


interface DietShoppingList2{
    veg: Veg[],
    fruit: Fruit[]
}


// correctly identifies that orange doesn't belong to veg but lets meat exist or any other food
const DietShoppingList2: DietShoppingList2 = {
    veg: ['corn', 'onion', 'orange'],
    fruit: ['banana'],
    meat: ['fish']
}

1 个答案:

答案 0 :(得分:0)

我为此here开枪了。看一看,让我知道你的想法。

type TBD<K, T> =
  & { [key: string]: never }
  & { [key: number]: never }
  & { [key in K & keyof T]: T[key] }

// correctly identifies that orange doesn't belong to veg & doesn't let meat any other food exist 
const dietShoppingList4: TBD<AllowedFoodGroups, DietShoppingList2> = {
    veg: ['corn', 'onion', 'orange'],
    fruit: ['banana'],
    meat: ['fish'],
    pulses: ['kidney bean', 'lima bean', 'lentil']
}

它不会产生与使用Record(即Object literal may only specify known properties, and 'meat' does not exist in type 'Record<AllowedFoodGroups, AllowedFood[]>')时相同的错误,但是它确实满足了限制键和值的目标,同时将键保留为一种类型并允许不同的键值类型。

对于TypeScript和类型我还是很陌生,因此也许还有另一种方法可以使无效键得到更好的错误。