Derzeit definiere ich die Konstruktorargumente und Instanzeigenschaften meiner Typescript-Klassen wie folgt:
interface ConstructorProps {
foo: number;
bar: string;
baz: boolean;
}
class MyClass {
foo: number;
bar: string;
baz: boolean;
constructor (props: ConstructorProps) {
this.foo = props.foo;
this.bar = props.bar;
this.baz = props.baz;
}
}
Welches ist ziemlich repetitiv. Gibt es eine Möglichkeit, dies sauberer zu machen, auch wenn dies nur für die Schnittstellen- und Instanzeigenschaften gilt?
Mit zugeordneten Typen und bedingten Typen können wir einen Typ erstellen, der alle Felder einer Klasse enthält, und ihn als Konstruktorargument verwenden. Wir können auch Object.assign
die Eigenschaften kopieren, anstatt jedes Feld zuzuweisen:
type NotMethods<T> = { [P in keyof T]: T[P] extends (...args: any[]) => any ? never: P }[keyof T];
type Fields<T> = { [P in NotMethods<T>]: T[P] }
class MyClass {
foo: number;
bar: string;
baz: boolean;
constructor(props: Fields<MyClass>) {
Object.assign(this, props)
}
method() {
}
}
new MyClass({
foo: 1,
bar: '',
baz: true
});
Spielplatz Link
Der Fields
Typ kann für jede Klasse wiederverwendet werden. Alle Felder der Klasse werden im Konstruktorargument benötigt.
Wenn Sie optionale Felder haben und strenge Nullprüfungen verwenden , können Sie eine Version schreiben, die die Optionalität des Felds im Konstruktorparameter beibehält:
type NotMethods<T> = Exclude<{ [P in keyof T]: T[P] extends (...args: any[]) => any ? never: P }[keyof T], undefined>;
type FilterUndefined<T, TKeys extends keyof T = keyof T> = Exclude<{ [P in TKeys]: undefined extends T[P] ? never: P }[TKeys], undefined>;
type KeepUndefined<T, TKeys extends keyof T = keyof T> = Exclude<TKeys, FilterUndefined<T, TKeys> | undefined>
type Fields<T> = { [P in FilterUndefined<T, NotMethods<T>>]: T[P] } & { [P in KeepUndefined<T, NotMethods<T>>]?: T[P] }
class MyClass {
foo: number;
bar: string;
baz?: boolean;
constructor(props: Fields<MyClass>) {
Object.assign(this, props)
props.foo
}
method() {
}
}
new MyClass({
foo: 1,
bar: '',
baz: true
});
new MyClass({
foo: 1,
bar: '',
});
Spielplatz Link
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen