我正在尝试使用以下模式:
enum Option {
ONE = 'one',
TWO = 'two',
THREE = 'three'
}
interface OptionRequirement {
someBool: boolean;
someString: string;
}
interface OptionRequirements {
[key: Option]: OptionRequirement;
}
这对我来说似乎很简单,但是我收到以下错误:
索引签名参数类型不能是联合类型。请考虑改用映射对象类型。
我究竟做错了什么?
key
的类型只能是字符串、数字或符号。枚举不是。
您可以使用 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".
}
最简单的解决方案是使用 Record
type OptionRequirements = Record<Options, OptionRequirement>
你也可以自己实现它:
type OptionRequirements = {
[key in Options]: OptionRequirement;
}
此构造仅适用于 type
,但不适用于 interface
。
您定义中的问题是说您的接口的键应该是 Options
类型,其中 Options
是枚举,而不是字符串、数字或符号。
key in Options
表示“对于那些在联合类型选项中的特定键”。
type
别名比 interface
更灵活、更强大。
如果您的类型不需要在课堂上使用,请选择 type
而不是 interface
。
[key in Options]: OptionRequirement | undefined
Record
输入中执行类似 keyof Options
的操作,它可以正常工作,但如果您通过“自己实现”路线执行此操作,则会出现语法错误,无法执行 [keyof Options]: OptionRequirement
。就我而言,我的 Option
是一种类型,而不是枚举。
Exclude
,您可以限制应在 Record
中实现哪些成员!
就我而言:
export type PossibleKeysType =
| 'userAgreement'
| 'privacy'
| 'people';
interface ProviderProps {
children: React.ReactNode;
items: {
// ↙ this colon was issue
[key: PossibleKeysType]: Array<SectionItemsType>;
};
}
我通过使用 in
运算符而不是使用 :
来修复它
~~~
interface ProviderProps {
children: React.ReactNode;
items: {
// ↙ use "in" operator
[key in PossibleKeysType]: Array<SectionItemsType>;
};
}
我有一些类似的问题,但我的情况是接口中的另一个字段属性,所以我的解决方案作为一个示例,带有可选字段属性和键的枚举:
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
}
不使用接口,而是使用映射对象类型
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
}
在我的例子中,我需要这些属性是可选的,所以我创建了这个泛型类型。
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
}
}
}
我有一个类似的问题。在创建角度表单验证器时,我试图只使用特定的键。
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 个密钥。
我遇到了类似的问题,我发现这个简单的解决方案对我来说就像一个魅力:只需将 [] 替换为 ():
interface OptionRequirements {
(key: Option): OptionRequirement;
}
在我的情况下,我需要使用联合类型而不是枚举,但两者都适合我:
type DocumentId = 'invoiceId' | 'orderId';
export interface INote {
id: number;
organizationId: number;
(key: DocumentId): number;
//...
}
interface OptionRequirements
更改为type OptionRequirements