Ich versuche das folgende Muster zu verwenden:
enum Option {
ONE = 'one',
TWO = 'two',
THREE = 'three'
}
interface OptionRequirement {
someBool: boolean;
someString: string;
}
interface OptionRequirements {
[key: Option]: OptionRequirement;
}
Dies scheint mir sehr einfach zu sein, ich erhalte jedoch den folgenden Fehler:
Ein Indexsignaturparametertyp kann kein Vereinigungstyp sein. Verwenden Sie stattdessen einen zugeordneten Objekttyp.
Was mache ich falsch?
javascript
typescript
John Maccarthy
quelle
quelle
key
kann nur eine Zeichenfolge, eine Zahl oder ein Symbol sein. Aufzählung ist nicht.Antworten:
Sie können den TS "in" -Operator verwenden und dies tun:
enum Options { ONE = 'one', TWO = 'two', THREE = 'three', } interface OptionRequirement { someBool: boolean; someString: string; } type OptionRequirements = { [key in Options]: OptionRequirement; // Note that "key in". }
quelle
interface OptionRequirements
zutype OptionRequirements
Die einfachste Lösung ist die Verwendung
Record
Sie können es auch selbst implementieren als:
type OptionRequirements = { [key in Options]: OptionRequirement; }
Dieses Konstrukt steht nur zur Verfügung
type
, aber nichtinterface
.Das Problem in Ihrer Definition besteht darin, dass der Schlüssel Ihrer Schnittstelle vom Typ sein sollte
Options
, wobeiOptions
es sich um eine Aufzählung handelt, nicht um eine Zeichenfolge, eine Zahl oder ein Symbol.Das
key in Options
bedeutet "für die spezifischen Schlüssel, die in den Union-Typ-Optionen enthalten sind".type
Alias ist flexibler und leistungsfähiger alsinterface
.Wenn Ihr Typ nicht im Unterricht verwendet werden muss, wählen
type
Sie ausinterface
.quelle
Ich hatte ein ähnliches Problem, aber mein Fall war mit einer anderen Feldeigenschaft in der Schnittstelle, so dass meine Lösung als Beispiel mit einer optionalen Feldeigenschaft mit einer Aufzählung für Schlüssel:
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 }
quelle
Verwenden Sie anstelle einer Schnittstelle einen zugeordneten Objekttyp
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 }
quelle
In meinem Fall mussten die Eigenschaften optional sein, also habe ich diesen generischen Typ erstellt.
type PartialRecord<K extends string | number | symbol, T> = { [P in K]?: T; };
Dann benutze es als solches:
type MyTypes = 'TYPE_A' | 'TYPE_B' | 'TYPE_C'; interface IContent { name: string; age: number; } interface IExample { type: string; partials: PartialRecord<MyTypes, IContent>; }
Beispiel
const example : IExample = { type: 'some-type', partials: { TYPE_A : { name: 'name', age: 30 }, TYPE_C : { name: 'another name', age: 50 } } }
quelle
Ich hatte ein ähnliches Problem. Ich habe versucht, beim Erstellen von Formularprüfern nur bestimmte Schlüssel zu verwenden.
export enum FormErrorEnum { unknown = 'unknown', customError = 'customError', } export type FormError = keyof typeof FormErrorEnum;
Und die Verwendung:
static customFunction(param: number, param2: string): ValidatorFn { return (control: AbstractControl): { [key: FormErrorEnum]?: any } => { return { customError: {param, param2} }; }; }
Dadurch kann 1 - X Anzahl von Schlüsseln verwendet werden.
quelle