我试着使用下面的模式:

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

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

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

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

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

我做错了什么?


当前回答

我也遇到过类似的问题。我试图在创建angular表单验证器时只使用特定的键。

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

export type FormError = keyof typeof FormErrorEnum;

以及用法:

static customFunction(param: number, param2: string): ValidatorFn {
  return (control: AbstractControl): { [key: FormErrorEnum]?: any } => {
    return { customError: {param, param2} };
  };
}

这将允许使用1 - X个键。

其他回答

我有一些类似的问题,但我的情况是在接口的另一个字段属性,所以我的解决方案作为一个可选字段属性的例子,有一个enum键:

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
}

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

type OptionRequirements = Record<Options, OptionRequirement>

你也可以自己实现:

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

此构造只对类型可用,而对接口不可用。

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

Options中的键表示“对于联合类型Options中的那些特定键”。

类型别名比接口更加灵活和强大。

如果你的类型不需要在类中使用,选择类型而不是接口。

我也遇到过类似的问题。我试图在创建angular表单验证器时只使用特定的键。

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

export type FormError = keyof typeof FormErrorEnum;

以及用法:

static customFunction(param: number, param2: string): ValidatorFn {
  return (control: AbstractControl): { [key: FormErrorEnum]?: any } => {
    return { customError: {param, param2} };
  };
}

这将允许使用1 - X个键。

你可以使用TS“in”操作符,这样做:

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

在我的例子中,我需要属性是可选的,所以我创建了这个泛型类型。

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
        }
    }
}