简体   繁体   English

定义一个Typescript接口,其中属性是现有对象的属性

[英]Define A Typescript Interface Where A Property Is An Existing Object's Properties

What is the best way to define an interface where one of the properties could be any of the properties on an existing object. 定义接口的最佳方法是,其中属性之一可以是现有对象上的任何属性。 In this case I have an object called fruits where I am simply storing a number of string constants and I want to define an interface (groceries) such that one of the properties (fruit) could be any of the string constants in the fruits object. 在这种情况下,我有一个名为fruits的对象,在这里我只是存储了许多字符串常量,并且我想定义一个接口(杂货),以便属性(fruit)之一可以是fruits对象中的任何字符串常量。

type Fruits = 'APPLE' | 'BANANA' | 'ORANGE';

const fruits = {
    APPLE: 'APPLE',
    BANANA: 'BANANA',
    ORANGE: 'ORANGE'
}

interface IGroceries {
    fruit: Fruits,
    vegetables: string[]
}

const initialGroceriesState: IGroceries = {
    fruit: fruits.APPLE,
    vegetables: []
}

This is my best attempt but this will throw an error saying: 这是我的最佳尝试,但这会引发错误:

Type '{ fruit: string; vegetables: never[]; }' is not assignable to type 'IGroceries'.
  Types of property 'fruit' are incompatible.
    Type 'string' is not assignable to type 'Fruits'.

One of the options is switching to string enum : 选项之一是切换到字符串枚举

enum Fruits {
    APPLE = 'APPLE',
    BANANA = 'BANANA',
    ORANGE = 'ORANGE'
}

interface IGroceries {
    fruit: Fruits,
    vegetables: string[]
}

const initialGroceriesState: IGroceries = {
    fruit: Fruits.APPLE,
    vegetables: []
}

Another option is correcting the typing of the existing object: 另一个选择是更正现有对象的类型:

type Fruits = 'APPLE' | 'BANANA' | 'ORANGE';

const fruits: { [key: string]: Fruits } = {
    APPLE: 'APPLE',
    BANANA: 'BANANA',
    ORANGE: 'ORANGE'
}

interface IGroceries {
    fruit: Fruits,
    vegetables: string[]
}

const initialGroceriesState: IGroceries = {
    fruit: fruits.APPLE,
    vegetables: []
}

fruits key values are inferred to strings. fruits键值被推断为字符串。 This results in error, because Fruits is assignable to string type but not vice versa. 这会导致错误,因为Fruits可分配给字符串类型,反之亦然。

In order to avoid this, fruits type should be specified explicitly: 为了避免这种情况,应显式指定fruits类型:

const fruits: { [K in Fruits]: K } = {
    APPLE: 'APPLE',
    BANANA: 'BANANA',
    ORANGE: 'ORANGE'
};

An another way is to use string enum, as another answer suggests. 另一种答案是,使用另一种方法是使用字符串枚举。 Depending on the case, this may or may not be desirable. 视情况而定,这可能是理想的,也可能是不理想的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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