Typescript leeres Objekt für eine typisierte Variable

85

Sagen wir, ich habe:

type User = {
...
}

Ich möchte ein neues userObjekt erstellen, aber es als leeres Objekt festlegen:

const user: User = {}; // This fails saying property XX is missing
const user: User = {} as any; // This works but I don't want to use any

Wie mache ich das? Ich möchte nicht, dass die Variable ist null.

Kousha
quelle
13
Entweder möchten Sie uservom Typ User | {}oder sein Partial<User>, oder Sie müssen den UserTyp neu definieren , um ein leeres Objekt zuzulassen. Im Moment sagt Ihnen der Compiler korrekt, dass dies userkein a ist User.
Jcalz

Antworten:

176

Vorsichtsmaßnahmen

Hier sind zwei würdige Vorbehalte aus den Kommentaren.

Entweder möchten Sie, dass der Benutzer vom Typ User | {}oder ist Partial<User>, oder Sie müssen den UserTyp neu definieren , um ein leeres Objekt zuzulassen. Im Moment teilt Ihnen der Compiler korrekt mit, dass der Benutzer kein Benutzer ist. - -jcalz

Ich denke nicht, dass dies als richtige Antwort angesehen werden sollte, da dadurch eine inkonsistente Instanz des Typs erstellt wird, die den gesamten Zweck von TypeScript untergräbt. In diesem Beispiel Usernamebleibt die Eigenschaft undefiniert, während die Typanmerkung besagt, dass sie nicht undefiniert sein kann. - -Ian Liu Rodrigues

Antworten

Eines der Entwurfsziele von TypeScript ist es, "ein Gleichgewicht zwischen Korrektheit und Produktivität herzustellen ". Wenn dies für Sie produktiv ist , erstellen Sie mit Type Assertions leere Objekte für typisierte Variablen.

type User = {
    Username: string;
    Email: string;
}

const user01 = {} as User;
const user02 = <User>{};

user01.Email = "[email protected]";

Hier ist ein Arbeitsbeispiel für Sie .

Hier sind Typzusicherungen, die mit Vorschlägen arbeiten.

Shaun Luttin
quelle
9
Vielen Dank! Das löst es! Dies sollte als die richtige Antwort markiert werden ...
Kokodoko
3
Ich denke nicht, dass dies als richtige Antwort angesehen werden sollte, da dadurch eine inkonsistente Instanz des Typs erstellt wird, die den gesamten Zweck von TypeScript untergräbt. In diesem Beispiel Usernamebleibt die Eigenschaft undefiniert, während die Typanmerkung besagt, dass sie nicht undefiniert sein kann.
Ian Liu Rodrigues
2
Guter Punkt @IanLiuRodrigues. Ich habe der Antwort einige Einschränkungen hinzugefügt.
Shaun Luttin
1
@IanLiuRodrigues Eines der Ziele von TypeScript ist es, Korrektheit mit Produktivität in Einklang zu bringen. Dies untergräbt also den gesamten Zweck von TypeScript und ist etwas extrem. github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
Shaun Luttin
21

Kommt wirklich darauf an, was du versuchst zu tun. Typen sind Dokumentationen in Typoskript, daher möchten Sie die Absicht zeigen, wie dieses Ding beim Erstellen des Typs verwendet werden soll.

Option 1: Wenn Benutzer während ihres Lebens möglicherweise einige, aber nicht alle Attribute haben

Machen Sie alle Attribute optional

type User = {
  attr0?: number
  attr1?: string
}

Option 2: Wenn Variablen, die Benutzer enthalten, mit null beginnen können

type User = {
...
}
let u1: User = null;

Wenn es hier darum geht, das Benutzerobjekt zu deklarieren, bevor bekannt ist, was ihm zugewiesen wird, möchten Sie wahrscheinlich auf let u1:Usereine Zuweisung verzichten.

Option 3: Was Sie wahrscheinlich wollen

Die Prämisse von Typoskript besteht darin, sicherzustellen, dass Sie dem mentalen Modell entsprechen, das Sie in Typen skizzieren, um Fehler zu vermeiden. Wenn Sie einem Objekt nacheinander Dinge hinzufügen möchten, ist dies eine Angewohnheit, die TypeScript versucht, Sie dazu zu bringen, dies nicht zu tun.

Wahrscheinlicher ist, dass Sie einige lokale Variablen erstellen und diese dann der benutzerhaltigen Variablen zuweisen möchten, wenn sie bereit ist, ein vollwertiger Benutzer zu sein. Auf diese Weise bleibt Ihnen niemals ein teilweise geformter Benutzer übrig. Diese Dinge sind eklig.

let attr1: number = ...
let attr2: string = ...
let user1: User = {
  attr1: attr1,
  attr2: attr2
}
Pixelpax
quelle
Ich bin mir nicht sicher, ob er dies wünscht oder nicht, aber es ist möglich, dass es sich um ein separates Argument namens UserAttributes handelt oder um etwas, das eingehende Parameter verarbeitet. Es ist möglicherweise kein akzeptables Benutzerobjekt und kann daher separat definiert werden.
Unflores
Dies sollte nicht die akzeptierte Antwort sein. Bitte sehen Sie Shaun Luttins Beitrag unten.
thargenediad
1

Sie können dies wie unten im Typoskript tun

 const _params = {} as any;

 _params.name ='nazeh abel'

Da sich Typenskript nicht wie Javascript verhält, müssen wir den Typ wie jeden anderen festlegen, da Sie sonst einem Objekt keine dynamische Eigenschaft zuweisen können

Nazehs
quelle
0

Wenn Sie ein leeres Objektliteral deklarieren und später Werte zuweisen, können Sie diese Werte als optional betrachten (möglicherweise vorhanden oder nicht vorhanden). Geben Sie sie daher einfach als optional mit einem Fragezeichen ein:

type User = {
    Username?: string;
    Email?: string;
}
CatalinBerta
quelle
0

Beachten Sie, dass die Verwendung const user = {} as UserTypenur Intellisense bereitstellt, zur Laufzeit userjedoch ein leeres Objekt ist {}und keine Eigenschaft enthält. das heißt user.Emailgeben undefinedstatt""

type UserType = {
    Username: string;
    Email: string;
}

So verwenden Sie classmit constructorfür tatsächlich Objekte mit Standardeigenschaften zu schaffen.

type UserType = {
  Username: string;
  Email: string;
};

class User implements UserType {
  constructor() {
    this.Username = "";
    this.Email = "";
  }

  Username: string;
  Email: string;
}

const myUser = new User();
console.log(myUser); // output: {Username: "", Email: ""}
console.log("val: "+myUser.Email); // output: ""

Sie können auch interfaceanstelle von verwendentype

interface UserType {
  Username: string;
  Email: string;
};

... und der Rest des Codes bleibt gleich.


Sie können das constructorTeil sogar überspringen und wie folgt verwenden:

class User implements UserType {
      Username = ""; // will be added to new obj
      Email: string; // will not be added
}

const myUser = new User();
console.log(myUser); // output: {Username: ""}
GorvGoyl
quelle