定义接口的最佳方法是,其中一个属性可以是现有对象的任何属性。在这种情况下,我有一个名为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: []
}
这是我最好的尝试,但这会引发错误说:
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'.
答案 0 :(得分:3)
其中一个选项是切换到string enum:
enum Fruits {
APPLE = 'APPLE',
BANANA = 'BANANA',
ORANGE = 'ORANGE'
}
interface IGroceries {
fruit: Fruits,
vegetables: string[]
}
const initialGroceriesState: IGroceries = {
fruit: Fruits.APPLE,
vegetables: []
}
另一个选项是更正现有对象的输入:
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: []
}
答案 1 :(得分:0)
fruits
键值被推断为字符串。这会导致错误,因为Fruits
可分配给字符串类型,但反之亦然。
为避免这种情况,应明确指定fruits
类型:
const fruits: { [K in Fruits]: K } = {
APPLE: 'APPLE',
BANANA: 'BANANA',
ORANGE: 'ORANGE'
};
另一种方法是使用字符串枚举,如另一个答案所示。根据具体情况,这可能是也可能不是。