【问题标题】:Define A Typescript Interface Where A Property Is An Existing Object's Properties定义一个 Typescript 接口,其中属性是现有对象的属性
【发布时间】:2018-05-23 05:02:27
【问题描述】:

定义接口的最佳方式是什么,其中一个属性可以是现有对象的任何属性。在这种情况下,我有一个名为 fruits 的对象,其中我只是存储了一些字符串常量,并且我想定义一个接口(杂货),以便其中一个属性(水果)可以是 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'.

【问题讨论】:

  • 简单地说:const initialGroceriesState:IGroceries = {水果:'APPLE',蔬菜:[]}

标签: javascript typescript


【解决方案1】:

其中一个选项是切换到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: []
}

【讨论】:

    【解决方案2】:

    fruits 键值被推断为字符串。这会导致错误,因为Fruits 可以分配给字符串类型,反之则不行。

    为了避免这种情况,应明确指定fruits 类型:

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

    另一种方法是使用字符串枚举,正如另一个答案所暗示的那样。根据具体情况,这可能是可取的,也可能是不可取的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-30
      • 2017-08-08
      • 2023-04-04
      • 1970-01-01
      • 2021-03-04
      • 2021-05-16
      • 2019-06-17
      相关资源
      最近更新 更多