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

时间:2019-01-30 10:10:28

标签: javascript typescript

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

enum Options {
  ONE = 'one',
  TWO = 'two',
  THREE = 'three',
}
interface OptionRequirement {
  someBool: boolean;
  someString: string;
}
interface OptionRequirements {
  [key: Options]: OptionRequirement;
}

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

  

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

我在做什么错了?

7 个答案:

答案 0 :(得分:7)

我有一些类似的问题,但我的情况是界面中的另一个字段属性,因此我的解决方案以可选字段属性为例,其中带有键枚举:

export enum ACTION_INSTANCE_KEY {
  cat = 'cat',
  dog = 'dog',
  cow = 'cow',
  book = 'book'
}

type ActionInstances = {
  [key in ACTION_INSTANCE_KEY]?: number; // cat id/dog id/cow id/ etc // <== optional
};

export interface EventAnalyticsAction extends ActionInstances { // <== need to be extended
  marker: EVENT_ANALYTIC_ACTION_TYPE; // <== if you wanna add another field to interface
}

答案 1 :(得分:4)

使用映射对象类型代替使用接口

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

type OptionKeys = keyof typeof Option;

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

type OptionRequirements = {                 // note type, not interface
  [key in OptionKeys]: OptionRequirement;   // key in
}

答案 2 :(得分:3)

最简单的解决方案是使用Record

type OptionRequirements = Record<Options, OptionRequirement>

您也可以自己将其实现为:

type OptionRequirements = {
  [key in Options]: OptionRequirement;
}

此构造仅可用于type,而不适用于interface

定义中的问题是,接口的键应为Options类型,其中Options是枚举,而不是字符串,数字或符号。

key in Options的意思是“对于联合类型“选项”中的那些特定键”。

type的别名比interface更加灵活和强大。

如果不需要在课堂上使用您的类型,请在type上选择interface

答案 3 :(得分:3)

您可以使用TS“ in”运算符,并执行以下操作:

enum Options {
  ONE = 'one',
  TWO = 'two',
  THREE = 'three',
}
interface OptionRequirement {
  someBool: boolean;
  someString: string;
}
interface OptionRequirements {
  [key in Options]: OptionRequirement; // Note that "key in".
}

答案 4 :(得分:2)

在我的情况下,我需要属性是可选的,因此我创建了这种通用类型。

type PartialRecord<K extends string | number | symbol, T> = { [P in K]?: T; };

然后按如下方式使用它:

type MyTypes = 'TYPE_A' | 'TYPE_B' | 'TYPE_C';

interface IContent {
    name: string;
    age: number;
}

interface IExample {
    type: string;
    partials: PartialRecord<MyTypes, IContent>;
}

示例

const example : IExample = {
    type: 'some-type',
    partials: {
        TYPE_A : {
            name: 'name',
            age: 30
        },
        TYPE_C : {
            name: 'another name',
            age: 50
        }
    }
}

答案 5 :(得分:0)

您不能使用enum作为键。

如果您确实需要解决方法,请参见以下答案:https://github.com/Microsoft/TypeScript/issues/2491#issuecomment-260864535

答案 6 :(得分:0)

我有一个类似的问题。创建角形验证器时,我只尝试使用特定键。

@implementation GDTCORClock

用法:

export enum FormErrorEnum {
  unknown = 'unknown',
  customError = 'customError',
}

export type FormError = keyof typeof FormErrorEnum;

这将允许使用1-X的键数。