391 Stimmen

TypeScript und Feldinitialisierungen

Wie initiiert man eine neue Klasse in TS auf diese Weise (Beispiel in C#, um zu zeigen, was ich will):

// ... some code before
return new MyClass { Field1 = "ASD", Field2 = "QWE" };
// ...  some code after

4voto

rostamiani Punkte 2153

Dies ist eine andere Lösung:

return {
  Field1 : "ASD",
  Field2 : "QWE" 
} as myClass;

3voto

stacksonstacks Punkte 31

Hier ist die beste Lösung, die ich für dieses Problem gefunden habe.

Deklarieren Sie eine Funktion, die als Dekorator verwendet werden kann. Ich nenne sie AutoReflect

export function AutoReflect<T extends { new(...args: any[]): {} }>(
  constructor: T
) {
  return class extends constructor {
    constructor(...args: any[]) {
      super(args)
      if (typeof args[0] === 'object') {
        Object.assign(this, args[0]);
      }
    }
  };
}

Dies bedeutet, dass im Konstruktor ein Objekt erwartet wird und die Mitglieder der Klasseninstanz zugewiesen werden. Verwenden Sie dies bei einer Klassendeklaration

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

@AutoReflect
class Person implements IPerson {
  name: string;
  number: number;
  constructor(model?: Partial<IPerson>){}
}

Im Konstruktor Ihres Modells können Sie das Modell optional machen, und bei der Verwendung des Partials können Sie eine neue Instanz erstellen, ohne alle Eigenschaftswerte zu setzen

new Person({
   name: 'Santa'
});

Diese Methode erzeugt eine neue Instanz der gewünschten Klasse und hat auch ein C#-Objektinitialisierungsgefühl.

2voto

Volodymyr Bobyr Punkte 187

Hier ist eine Lösung, die:

  • zwingt Sie nicht dazu, alle Felder optional zu machen (im Gegensatz zu Partial<...> )
  • unterscheidet zwischen Klassenmethoden und Feldern vom Funktionstyp (im Gegensatz zu der OnlyData<...> Lösung)
  • bietet eine schöne Struktur durch die Definition einer Params-Schnittstelle
  • muss Variablennamen und -typen nicht mehr als einmal wiederholen

Der einzige Nachteil ist, dass es siehe anfangs komplizierter.

// Define all fields here
interface PersonParams {
  id: string
  name?: string
  coolCallback: () => string
}

// extend the params interface with an interface that has
// the same class name as the target class
// (if you omit the Params interface, you will have to redeclare
// all variables in the Person class)
interface Person extends PersonParams { }

// merge the Person interface with Person class (no need to repeat params)
// person will have all fields of PersonParams
// (yes, this is valid TS)
class Person {
  constructor(params: PersonParams) {
    // could also do Object.assign(this, params);

    this.id = params.id;
    this.name = params.name;

    // intellisence will expect params
    // to have `coolCallback` but not `sayHello`
    this.coolCallback = params.coolCallback;
  }

  // compatible with functions
  sayHello() {
    console.log(`Hi ${this.name}!`);
  }
}

// you can only export on another line (not `export default class...`)
export default Person;

1voto

Adel Tabareh Punkte 1172

Wenn Sie eine alte Version von Typescript < 2.1 verwenden, können Sie eine ähnliche Funktion wie die folgende verwenden, die im Grunde ein Casting eines beliebigen typisierten Objekts ist:

const typedProduct = <Product>{
                    code: <string>product.sku
                };

HINWEIS: Diese Methode ist nur für Datenmodelle geeignet, da sie alle alle Methoden des Objekts entfernt. Es ist im Grunde ein Casting jedes Objekts in ein typisiertes Objekt

1voto

Peter Pompeii Punkte 1357

Am einfachsten geht das mit dem Type Casting.

return <MyClass>{ Field1: "ASD", Field2: "QWE" };

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X