索引签名参数类型不能是联合类型。考虑改用映射对象类型

新手上路,请多包涵

我正在尝试使用以下模式:

 enum Option {
  ONE = 'one',
  TWO = 'two',
  THREE = 'three'
}

interface OptionRequirement {
  someBool: boolean;
  someString: string;
}

interface OptionRequirements {
  [key: Option]: OptionRequirement;
}

这对我来说似乎很简单,但是我收到以下错误:

索引签名参数类型不能是联合类型。请考虑改用映射对象类型。

我究竟做错了什么?

原文由 john maccarthy 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.7k
1 个回答

已编辑

TL;DR:使用 Record<type1,type2> 或映射对象,例如:

 type YourMapper = {
    [key in YourEnum]: SomeType
}

我遇到了类似的问题,问题是键的允许类型是字符串、数字、符号或模板文字类型。

因此,正如 Typescript 所建议的,我们可以使用映射对象类型:

 type Mapper = {
    [key: string]: string;
}

请注意在 map 对象中我们只允许使用字符串、数字或符号作为键,所以如果我们想使用特定的字符串(即 emum 或联合类型),我们应该在里面使用 in 关键字索引签名。这用于引用枚举或联合中的特定属性。

 type EnumMapper = {
  [key in SomeEnum]: AnotherType;
};

在一个真实的例子中,假设我们想要得到这个结果,一个对象,它的键和值都是指定的类型:

   const notificationMapper: TNotificationMapper = {
    pending: {
      status: EStatuses.PENDING,
      title: `${ENotificationTitels.SENDING}...`,
      message: 'loading message...',
    },
    success: {
      status: EStatuses.SUCCESS,
      title: ENotificationTitels.SUCCESS,
      message: 'success message...',
    },
    error: {
      status: EStatuses.ERROR,
      title: ENotificationTitels.ERROR,
      message: 'error message...'
    },
  };

为了使用 Typescript 实现这一点,我们应该创建不同的类型,然后在 Record<> 或映射对象类型中实现它们:

 export enum EStatuses {
  PENDING = 'pending',
  SUCCESS = 'success',
  ERROR = 'error',
}

interface INotificationStatus {
  status: string;
  title: string;
  message: string;
}

//option one, Record:
type TNotificationMapper = Record<EStatuses, INotificationStatus>

//option two. mapped object:
type TNotificationMapper = {
  [key in EStatuses]:INotificationStatus;
}

 interface OptionRequirements {
  (key: Option): OptionRequirement;
}

这里我使用枚举,但这种方法适用于枚举和联合类型。

*注意-使用括号而不是方括号的类似语法(即这 (...) 而不是这个 [...] ,可能不会显示任何错误,但它表示完全不同的东西,一个函数界面,所以这个:

 interface Foo {
(arg:string):string;
}

实际上是在描述一个函数签名,例如:

 const foo = (arg:string) => string;

原文由 Joe 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题