Yazılan bir değişken için Typescript boş nesnesi


88

Sahip olduğumu söyle:

type User = {
...
}

Yeni bir tane oluşturmak userama onu boş bir nesne olarak ayarlamak istiyorum :

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

Bunu nasıl yaparım? Değişkenin olmasını istemiyorum null.


15
Ya usertipte olmak istersiniz User | {}ya Partial<User>da Userboş bir nesneye izin vermek için türü yeniden tanımlamanız gerekir . Şu anda, derleyici size doğru bir şekilde bunun usera olmadığını söylüyor User.
jcalz

Yanıtlar:


186

Uyarılar

İşte yorumlardan iki değerli uyarı.

Kullanıcının tipte olmasını istersiniz User | {}veya boş bir nesneye izin vermek Partial<User>için Usertürü yeniden tanımlamanız gerekir . Şu anda, derleyici size doğru bir şekilde kullanıcının bir Kullanıcı olmadığını söylüyor. -jcalz

Bunun doğru bir cevap olarak görülmesi gerektiğini düşünmüyorum çünkü bu, TypeScript'in tüm amacını baltalayarak türün tutarsız bir örneğini yaratıyor. Bu örnekte, özellik Usernametanımsız bırakılırken, tür ek açıklaması bunun tanımsız olamayacağını söylüyor. -Ian Liu Rodrigues

Cevap

Biri typescript tasarım hedefleri etmektir "doğruluk ve verimlilik arasında bir denge." Bunu yapmak sizin için verimli olacaksa, yazılan değişkenler için boş nesneler oluşturmak üzere Tür İddialarını kullanın.

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

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

user01.Email = "foo@bar.com";

İşte size çalışan bir örnek .

İşte öneri ile çalışan tip iddiaları.


9
Teşekkür ederim! Bu onu çözer! Bu doğru cevap olarak işaretlenmelidir ...
Kokodoko

3
Bunun doğru bir cevap olarak görülmesi gerektiğini düşünmüyorum çünkü bu, TypeScript'in tüm amacını baltalayarak türün tutarsız bir örneğini yaratıyor. Bu örnekte, özellik Usernametanımsız bırakılırken, tür ek açıklaması tanımsız olamayacağını söylüyor.
Ian Liu Rodrigues

2
İyi nokta @ IanLiuRodrigues. Cevaba bazı uyarılar ekledim.
Shaun Luttin

1
@IanLiuRodrigues TypeScript'in hedeflerinden biri, doğruluk ile üretkenliği dengelemektir, dolayısıyla bunun TypeScript'in tüm amacını baltaladığını söylemek biraz aşırıdır. github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
Shaun Luttin

22

Gerçekten ne yapmaya çalıştığına bağlı. Türler, typcript'teki belgelerdir, bu nedenle, türü oluştururken bu şeyin nasıl kullanılması gerektiği konusunda niyet göstermek istersiniz.

1. Seçenek: Kullanıcılar, yaşamları boyunca bazı özelliklere sahip olabilir, ancak tüm özelliklere sahip olmayabilirse

Tüm özellikleri isteğe bağlı yapın

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

Seçenek 2: Kullanıcılar içeren değişkenler boş başlayabilirse

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

Yine de, gerçekten, burada amaç, kendisine neyin atanacağı bilinmeden önce Kullanıcı nesnesini bildirmekse, muhtemelen let u1:Userherhangi bir atama yapmadan yapmak istersiniz .

3. Seçenek: Muhtemelen ne istiyorsunuz

Gerçekten, typcript'in öncülü, hata yapmaktan kaçınmak için türlerde ana hatlarıyla belirlediğiniz zihinsel modele uyduğunuzdan emin olmaktır. Bir nesneye tek tek bir şeyler eklemek istiyorsanız, bu, TypeScript'in yapmamanızı sağlamaya çalıştığı bir alışkanlıktır.

Daha büyük olasılıkla, bazı yerel değişkenler oluşturmak ve ardından tam Kullanıcı olmaya hazır olduğunda Kullanıcı içeren değişkene atamak istersiniz. Bu şekilde, asla kısmen oluşturulmuş bir Kullanıcıyla kalmazsınız. Bu şeyler iğrenç.

let attr1: number = ...
let attr2: string = ...
let user1: User = {
  attr1: attr1,
  attr2: attr2
}

Bunun peşinde olup olmadığından emin değilim, ancak UserAttributes adında ayrı bir argümandan veya gelen parametreleri işleyen bir şeyden bahsediyor olmamız mümkündür. Kabul edilebilir bir kullanıcı nesnesi olmayabilir ve bu nedenle ayrı ayrı tanımlanabilir.
2018

Kabul edilen cevap bu olmamalı. Lütfen aşağıdaki Shaun Luttin gönderisine bakın.
thargenediad

2

bunu aşağıdaki gibi typcript'te yapabilirsiniz

 const _params = {} as any;

 _params.name ='nazeh abel'

typcript javascript gibi davranmadığından, türü herhangi bir şekilde yapmalıyız, aksi takdirde bir nesneye dinamik olarak özellik atamanıza izin vermez


2

Kullanmanın const user = {} as UserTypesadece intellisense sağladığını, ancak çalışma zamanında userboş bir nesne olduğunu {}ve içinde hiçbir özelliği olmadığını unutmayın. bu demek oluyor ki yerine user.Emailverecekundefined""

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

Bu nedenle, varsayılan özelliklere sahip nesneler oluşturmak için classwith kullanın constructor.

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: ""

Bunun interfaceyerine de kullanabilirsiniztype

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

... ve kodun geri kalanı aynı kalır.


Aslında, constructorbölümü atlayabilir ve şu şekilde kullanabilirsiniz:

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: ""}

1

Boş bir nesne değişmezi bildirir ve daha sonra değerler atarsanız, bu değerleri isteğe bağlı olarak değerlendirebilirsiniz (orada olabilir veya olmayabilir), bu nedenle bunları isteğe bağlı olarak bir soru işaretiyle yazın:

type User = {
    Username?: string;
    Email?: string;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.