TypeScript'te bir arabirim dosyası tanımına dayalı olarak nasıl nesne oluşturabilirim?


313

Ben böyle bir arayüz tanımladık:

interface IModal {
    content: string;
    form: string;
    href: string;
    $form: JQuery;
    $message: JQuery;
    $modal: JQuery;
    $submits: JQuery;
 }

Ben böyle bir değişken tanımlayın:

var modal: IModal;

Ancak, modal özelliğini ayarlamaya çalıştığımda bana şunu söyleyen bir mesaj veriyor:

"cannot set property content of undefined"

Kalıcı nesneyi tanımlamak için bir arabirim kullanmak uygun mudur ve öyleyse bunu nasıl oluşturmalıyım?

Yanıtlar:


426

Başka bir yerde "kalıcı" değişkeni oluşturuyorsanız ve TypeScript'e bunların tamamının yapıldığını söylemek istiyorsanız, şunu kullanırsınız:

declare const modal: IModal;

TypeScript'te aslında IModal örneği olacak bir değişken oluşturmak istiyorsanız, onu tam olarak tanımlamanız gerekir.

const modal: IModal = {
    content: '',
    form: '',
    href: '',
    $form: null,
    $message: null,
    $modal: null,
    $submits: null
};

Ya da, bir tür iddiası ile yalan söyleyin, ancak erişim modal.contentsırasında vb.

const modal = {} as IModal;

Örnek Sınıf

class Modal implements IModal {
    content: string;
    form: string;
    href: string;
    $form: JQuery;
    $message: JQuery;
    $modal: JQuery;
    $submits: JQuery;
}

const modal = new Modal();

"Bu gerçekten arayüzün bir kopyası" diyebilirsiniz - ve haklısınız. Modal sınıfı, IModal arabiriminin tek uygulamasıysa, arabirimi tamamen silmek ve kullanmak isteyebilirsiniz ...

const modal: Modal = new Modal();

Ziyade

const modal: IModal = new Modal();

2
Teşekkürler. Başlangıçta tüm modal içerikleri tanımlamaktan kurtulmayı umuyordum. Bir arabirim yerine, Modal'ı özelliklere sahip bir sınıf olarak tanımlayıp daha sonra başlangıç ​​değerlerinin tümünü ayarlamak için yeni ve bir yapıcı kullansaydım daha kolay olur muydu?

1
Evet - bir sınıf tanımlayabilirsiniz ve sonra yalnızca bunlara ihtiyacınız olduğunda yeni örnekler oluşturmanız gerekir. Bir örneğe mi ihtiyacınız var?
Fenton

2
Arayüz hakkında bir örnek ve bir not ekledim.
Fenton

21
var modal = <IModal>{};Bu aradığım şey ;-) teşekkürler!
Efsaneler

5
Bilginize, kullanmak {} as IModalyerine kullanmak daha iyidir <IModal>{}. <foo>JSX'te stil iddialarını kullanırken dil gramerinde belirsizliği kaldırır . Daha fazlasını okuyun . Ve tabii ki, yerine letveya constkullanın var.
Alex Klaus

191

Bir arabirimin boş bir nesnesini istiyorsanız, şunları yapabilirsiniz:

var modal = <IModal>{};

Verileri yapılandırmak için arabirimler yerine arabirimler kullanmanın avantajı, sınıfta herhangi bir yönteminiz yoksa, derlenmiş JS'de boş bir yöntem olarak gösterilmesidir. Misal:

class TestClass {
    a: number;
    b: string;
    c: boolean;
}

içine derlemek

var TestClass = (function () {
    function TestClass() {
    }
    return TestClass;
})();

ki bu değer taşımaz. Diğer yandan arayüzler, veri yapılandırma ve tip kontrolünün faydalarını sunarken JS'de hiç görünmüyor.


1
`Yukarıdaki yoruma eklemek için. Bir işlevi "updateModal (IModal modalInstance) {}" olarak adlandırmak için, 'IModal' arayüzünün satır içi bir örneğini oluşturabilirsiniz, şöyle: // updateModal işlevinin ve IModal'ın erişilebilir olduğu bazı kodlar burada: updateModal (<IModal> {// bu satır bir örnek içeriği oluşturur: '', form: '', href: '', $ form: null, $ message: null, $ modal: null, $ submits: null}); // kodunuzu `kapalı tamamlamak
Güneşli

kullanarak var modal= <abc>{}biz sadece boş nesnenin abc tipi modal atadık ama nerede modal türü ilan ettik? typescript6 kullanıyorum.
Pardeep Jain

Bu benim için işe yaramadı Kabul edilen cevapta belirtildiği gibi tüm nesneyi başlatmak zorunda kaldım.
Rahul Sonwanshi


22

Bence bunu yapmak için beş farklı seçeneğiniz var . Aralarından seçim yapmak, ulaşmak istediğiniz hedefe bağlı olarak kolay olabilir.

Çoğu durumda bir sınıf kullanmanın ve onu başlatmanın en iyi yolu , çünkü yazım denetimini uygulamak için TypeScript kullanıyorsunuz.

interface IModal {
    content: string;
    form: string;
    //...

    //Extra
    foo: (bar: string): void;
}

class Modal implements IModal {
    content: string;
    form: string;

    foo(param: string): void {
    }
}

Diğer yöntemler bir arabirimden nesne oluşturmanın daha kolay yollarını sunsa bile, nesnenizi farklı konular için kullanıyorsanız ve arabirimin aşırı ayrılmasına neden olmazsa: Arabiriminizi ayırmayı düşünmelisiniz :

interface IBehaviour {
    //Extra
    foo(param: string): void;
}

interface IModal extends IBehaviour{
    content: string;
    form: string;
    //...
}

Öte yandan, örneğin kodunuzu birim sınama sırasında (endişelerinizi sık sık ayırmıyorsanız) verimlilik uğruna dezavantajları kabul edebilirsiniz. Çoğunlukla büyük üçüncü taraf * .d.ts arayüzleri için alay oluşturmak için başka yöntemler uygulayabilirsiniz. Ve her büyük arayüz için her zaman tam anonim nesneler uygulamak acı verici olabilir.

Bu yolda ilk seçeneğiniz boş bir nesne oluşturmaktır :

 var modal = <IModal>{};

İkincisi , arayüzünüzün zorunlu kısmını tam olarak gerçekleştirmek için . 3. taraf JavaScript kitaplıklarını çağırıyor olsanız da yararlı olabilir, ancak bunun yerine daha önce olduğu gibi bir sınıf oluşturmanız gerektiğini düşünüyorum:

var modal: IModal = {
    content: '',
    form: '',
    //...

    foo: (param: string): void => {
    }
};

Üçüncü olarak , arayüzünüzün yalnızca bir bölümünü oluşturabilir ve anonim bir nesne oluşturabilirsiniz , ancak bu şekilde sözleşmeyi yerine getirmekle sorumlusunuz

var modal: IModal = <any>{
    foo: (param: string): void => {

    }
};

Arayüzler isteğe bağlı olsa bile cevabımı özetlerken, JavaScript koduna aktarılmadığından, TypeScript akıllıca ve tutarlı bir şekilde kullanıldığında yeni bir soyutlama düzeyi sağlamak için oradadır. Bence, sadece çoğu durumda bunları kendi kodunuzdan reddedebilirsiniz çünkü yapmamalısınız.



12

Üstte eşit bir cevap bulamadığım ve cevabım farklı olduğu için. Yaparım:

modal: IModal = <IModal>{}

2

Arayüzünüzü kullanarak şunları yapabilirsiniz:

class Modal() {
  constructor(public iModal: IModal) {
   //You now have access to all your interface variables using this.iModal object,
   //you don't need to define the properties at all, constructor does it for you.
  }
}

2

İşte başka bir yaklaşım:

Bunun gibi ESLint dostu bir nesne oluşturabilirsiniz

const modal: IModal = {} as IModal;

Veya arabirime dayalı ve varsa varsayılan varsayılanlara sahip varsayılan bir örnek

const defaultModal: IModal = {
    content: "",
    form: "",
    href: "",
    $form: {} as JQuery,
    $message: {} as JQuery,
    $modal: {} as JQuery,
    $submits: {} as JQuery
};

Ardından, varsayılan örneğin bazı özellikleri geçersiz kılarak varyasyonları

const confirmationModal: IModal = {
    ...defaultModal,     // all properties/values from defaultModal
    form: "confirmForm"  // override form only
}

1

Şimdiye kadar yayınlanan çözümlerin birçoğu tip iddialarını kullanır ve bu nedenle uygulamada gerekli arayüz özellikleri atlanırsa derleme hataları atmaz.

Diğer sağlam ve kompakt çözümlerle ilgilenenler için :

Seçenek 1: Arabirimi uygulayan anonim bir sınıf oluşturun:

new class implements MyInterface {
  nameFirst = 'John';
  nameFamily = 'Smith';
}();

2. Seçenek: Bir yardımcı program işlevi oluşturun:

export function impl<I>(i: I) { return i; }

impl<MyInterface>({
  nameFirst: 'John';
  nameFamily: 'Smith';
})

0

Tuşlarını kullanarak varsayılan değerleri ayarlayabilirsiniz Class.

Sınıf Yapıcısı Olmadan:

interface IModal {
  content: string;
  form: string;
  href: string;
  isPopup: boolean;
};

class Modal implements IModal {
  content = "";
  form = "";
  href: string;  // will not be added to object
  isPopup = true;
}

const myModal = new Modal();
console.log(myModal); // output: {content: "", form: "", isPopup: true}

Sınıf Yapıcı ile

interface IModal {
  content: string;
  form: string;
  href: string;
  isPopup: boolean;
}

class Modal implements IModal {
  constructor() {
    this.content = "";
    this.form = "";
    this.isPopup = true;
  }

  content: string;

  form: string;

  href: string; // not part of constructor so will not be added to object

  isPopup: boolean;
}

const myModal = new Modal();
console.log(myModal); // output: {content: "", form: "", isPopup: true}
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.