An index signature parameter type cannot be a union type. Consider using a mapped object type ins...

最近在写接口类型时,希望一个类型的键值是联合类型中固定的几个

const enum INFO_KEYS{
    TEL = 'tel',
    AGE = 'age',
// or
// type IInfoKeys = 'tel' | 'age';
export interface IPersonnalInfo = {
    area_id: number;
    area_name: string;
    [key: INFO_KEYS]: number;       // or [key: IInfoKeys]: number;

但是却得到错误提示

An index signature parameter type cannot be a union type. Consider using a mapped object type instead. ts(1337)

在github上找到了quick fix解决方法,先附上链接:https://github.com/Microsoft/TypeScript/issues/24220

下面是我对解决方法的总结

解决该问题,我们只需要注意以下三个地方

使用[key in INFO_KEYS],而不是[key: INFO_KEYS]
这也是很多回答给出的方案,但事实上?
export interface IPersonnalInfo = {
    area_id: number;
    area_name: string;
    [key in INFO_KEYS]: number

在使用in之后,仍然会得到错误提示

A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type. ts(1169)

A computed property name must be of type 'string', 'number', 'symbol', or 'any'. ts(2464)

因为接下来还有两点需要注意

  • 如果类型是interface,使用type类型别名替换
  • export type IPersonnalInfo = {
        area_id: number;
        area_name: string;
        [key in INFO_KEYS]: number;
    
  • 分离类型中的其他成员,使用相交类型来组织它们
  • type IAreaInfo = {       //type or interface
         area_id: number;
         area_name: string;
    export type IPersonnalInfo = {
        [key in INFO_KEYS]: number;
    } & IAreaInfo;
    

    如果注意了以上三点 ,我们最终得到的代码会是这样,并且没有错误提示

    const enum INFO_KEYS{
        TEL = 'tel',
        AGE = 'age'
    // or
    // type IInfoKeys = 'tel' | 'age';
    type IAreaInfo = {
        area_id: number;
        area_name: string;