如何在打字稿中创建可选的对象关键字字符串?

时间:2019-07-22 11:32:26

标签: javascript typescript

declare interface timezoneSyntax {
  region: string;
  en: {
    x: string;
    offset: {
      EST?: number;
      EDT?: number;
      [key: string]: number;
    };
  };
  it: {
   x: string;
  }
}

如何使以下对象成为可选对象,并使en成为通用对象?

en: {
    x: string;
    offset: {
      EST?: number;
      EDT?: number;
      [key: string]: number;
    };
  };

我尝试将en转换为[key: string]?,但是显示错误。请指教。

2 个答案:

答案 0 :(得分:4)

[key: string]: T形式的索引始终被视为可选索引,因此无需使用?表示法进行指定。

但是,指定这样的索引签名会强制 all 接口属性具有与键相同的T类型。例如,region将导致

  

类型'string'的属性'region'不能分配给字符串索引类型'{x:string;偏移量:{...}; }'

这是因为索引签名[key: string]: T仅指示 all 接口属性应如何。一种替代方法是使用[key: string]: any,但会放宽类型安全性。

根据我的理解,这不是您想要的副作用,因此您应该重新考虑在此界面中使用索引键并找到其他方法。

提案

不要使用特定于语言的属性名称(enites等),而应使用通用的language作为名称。如果您还需要知道使用哪种语言,则应将其作为language添加到name模型中。

您最终会得到这样的东西:

declare interface timezoneSyntax {
  region: string;
  language: {
    name: string; // `en`, `it`, `es`, etc
    x: string;
    offset: {
      EST?: number;
      EDT?: number;
      [key: string]: number;
    };
  };
}

进一步阅读

Indexable Types - Official TypeScript Documentation

Index Signatures - TypeScript Deep Dive

答案 1 :(得分:-1)

顺便说一句,它已经成为可选的。但是,如果您仍然想明确地执行该操作,则可以执行以下操作。

declare interface timezoneSyntax {
  region: string;
  en: {
    x: string;
    offset:
      | {
          EST?: number;
          EDT?: number;
          [key: string]: number;
        }
      | {
          EST?: number;
          EDT?: number;
        };
  };
  it: {
    x: string;
  };
}