【问题标题】:How can I define an interface for a object/array containing key/value pairs as well as nested objects?如何为包含键/值对以及嵌套对象的对象/数组定义接口?
【发布时间】:2019-07-30 08:32:33
【问题描述】:

我正在输入一个本地化库,并且我的目标是使其具有强类型(因为它将在多个角度应用程序中重复使用)并且 - 同时 - 向后兼容,因此我们赢了'不必重写所有现有的本地化文件。

但是,上述本地化文件的结构让我有点头疼。举例:

{
  'any-random-key': 'This is a string',
  'another-random-key': {
    'random-key': 'This is a string'
  },
  'yet-another-random-key': {
    'random-key-2': 'This is a string',
    'random-key-3': {
      'random-key-4': 'This is a string',
      'random-key-5': {
        'random-key-6': 'This is a string'
      }
    }
  },
  'and-yet-another-random-key': {
    'random-key-6': {
      'random-key-7': {
        'random-key-8': 'This is a string'
      },
      'random-key-9': 'This is a string'
    }
  }
}

现在 - 我想我可以说该服务接受 translations: anytranslations: object - 但这对我来说有点太随意了(不是双关语)。

所以我尝试使用两种不同的接口:

export interface ITranslation {
  [s: string]: string;
}

export interface ITranslations {
  [s: string]: ITranslation;
}

但是,any-random-key 说:Type 'string' is not assignable to type 'ITranslation' 失败

所以我调整了我的ITranslations-interface 使其变为

export interface ITranslations {
  [s: string]: ITranslation | string;
}

修复了上述错误,但在'and-yet-another-random-key' 上引入了一个新错误,说Property ''and-yet-another-random-key'' is incompatible with index signature.

在这一点上,我有点难过。我想要实现的目标(遗留结构的强类型)根本不合理吗?

【问题讨论】:

  • 嵌套层级任意深?对于'and-yet-another-random-key',它是 3 级深度,而您的界面仅处理 2 级深度对象。
  • 这看起来像树状结构

标签: typescript interface


【解决方案1】:

对于任意级别的嵌套(换句话说,您的数据对象可以有任意多的级别),您可以简单地像这样自引用接口:

/** @interface */
export interface ITranslations {
  [s: string]: ITranslations | string;
}

See the above example on TypeScript playground.


如果您只想允许 3 级深度嵌套,那么界面必须是冗长的:TypeScript 不允许您定义“深度”(即嵌套的程度):

/** @interface */
export interface ITranslations<T = string> {
  [s: string]: T | string;
}

/** @type */
export type ITranslationsMax3Levels = ITranslations<ITranslations<ITranslations<ITranslations>>>;

const data: ITranslationsMax3Levels = { ... }

See the above example on TypeScript playground.

【讨论】:

    【解决方案2】:

    似乎解决方案比我想象的要容易:

    export interface ITranslations {
      [s: string]: ITranslations | ITranslation | string;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-07-02
      • 1970-01-01
      • 1970-01-01
      • 2023-01-05
      • 1970-01-01
      • 1970-01-01
      • 2019-04-26
      • 2021-12-08
      • 1970-01-01
      相关资源
      最近更新 更多