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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何键入属性和值均来自其他类型的对象相关的知识,希望对你有一定的参考价值。

我想输入一个对象,其中属性值是仅允许为某种类型的数组,而其属性也仅允许为某种类型(联合类型)。我在下面尝试了两种不同的方法。带有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']
}
答案

我为此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和类型仍然很陌生,所以也许还有另一种方法可以对无效键给出更好的错误。

以上是关于如何键入属性和值均来自其他类型的对象的主要内容,如果未能解决你的问题,请参考以下文章

根据来自不同对象数组的属性和值过滤对象数组

如何从数组中的对象添加新的键和值?

从数组中拆分出对象属性和值[重复]

如何使用来自其他活动android的片段打开一个活动

使用类型中的“in”键入具有计算属性的类型

在代码片段中包含类型转换