2012-10-25 14 views
7

Używam Backbone.Marionette w maszynie do pisania. Napisałem swój własny opis typu Marionetki.Jak mogę powiedzieć TypeScript o dynamicznym dodawaniu właściwości?

var ProviderSpa = new Backbone.Marionette.Application(); 
ProviderSpa.addRegions({ 
    'servicesRegion': "#services-offered" 
}); 
ProviderSpa.servicesRegion.show(); 

Moim problemem jest to, że addRegions ma efekt uboczny dodawanie właściwości do ProviderSpa maszynopis, który nie wie o, a więc narzeka, że ​​„własność«servicesRegion»nie istnieje na wartości typu” Backbone. Marionette.Application ".

Jak mogę powiedzieć TypeScript o tych dynamicznych właściwościach dodatków do instancji typu?

Odpowiedz

0

Efekty uruchomieniowe nie mogą być rozpatrywane przez system typu TypeScript, ponieważ typy TypeScript istnieją tylko w czasie kompilacji. Będziesz musiał wpisać ProviderSpa odpowiednio podczas kompilacji. Być może najprostszym sposobem na to jest zrobić interfejs do ProviderSpa który ma addRegions i typy servicesRegion więc można zrobić:

interface IProviderSpa { servicesRegion: ...; addRegions: ...; }; 
var ProviderSpa = <IProviderSpa> new Backbone.Marionette.Application(); 

Jeśli Marionette ma typ interfejsu dla aplikacji, można nawet rozszerzyć że tak:

interface IProviderSpa extends Backbone.Marionette.IApplication { ... } 
3

Do tego przykładu użyłem wyciętej definicji marionetki BackBone.

Jeśli do obiektu dodawanych jest wiele dynamicznych właściwości, można pozostawić rzeczy dynamiczne zamiast próbować tworzyć deklaracje lub interfejsy dla nich wszystkich - szczególnie w przypadku konieczności aktualizowania deklaracji za pomocą nowych Właściwości i zalety posiadania statycznego pisania na to, co faktycznie są właściwościami dynamicznymi, nie jest kosztem, który bym zapłacił.

W tym przykładzie uzyskanie dostępu do właściwości przy użyciu składni nawias kwadratowy oznacza, że ​​pomyślnie przechodzi sprawdzanie typu bez potrzeby deklarowania. Ważny bit jest na ostatniej linii.

Możesz przetestować to na TypeScript playground.

declare module Backbone { 
    export module Marionette { 
     export class Application { 
      addRegions(regions: any): void; 
     } 
    } 
} 

var servicesRegion = 'servicesRegion'; 
var ProviderSpa = new Backbone.Marionette.Application(); 
ProviderSpa.addRegions({ 
    servicesRegion: "#services-offered" 
}); 
ProviderSpa[servicesRegion].show(); 
2

Właściwie TypeScript i Marionetka pasują do dłoni.
Kluczem jest tutaj myślenie w kategoriach klas zamiast właściwości dynamicznych. Mając to na uwadze, Twój kod powyżej staje się w ten sposób:

class ProviderSpa extends Marionette.Application { 
servicesRegion: Marionette.Region; 
constructor(options?: any) { 
    super(options); 
    this.addRegions({ servicesRegion: "#services-offered" }); 
} 
} 

var providerSpa = new ProviderSpa(); 
providerSpa.show(); 

Aktualizacja:
Właśnie napisali część 1 z blogu na TypeScript: Using Backbone.Marionette and RESTful WebAPI.

Powiązane problemy