2012-10-25 10 views
7

Sto usando Backbone.Marionette in Typescript. Ho scritto la mia descrizione del tipo di burattino.Come dire a TypeScript sull'aggiunta dinamica delle proprietà?

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

Il mio problema è che addRegions ha un effetto collaterale di aggiungere proprietà alle ProviderSpa, che dattiloscritto non sa nulla e quindi si lamenta che 'La proprietà 'servicesRegion' non esiste sul valore di tipo' Backbone. Marionette.Application'.

Come posso dire a TypeScript di queste aggiunte di proprietà dinamiche a un'istanza di un tipo?

risposta

0

Gli effetti di runtime non possono essere considerati dal sistema di tipi TypeScript poiché i tipi di TypeScript esistono solo in fase di compilazione. Dovrai digitare ProviderSpa appropriatamente al momento della compilazione. Forse il modo più semplice per farlo è fare un'interfaccia per ProviderSpa che ha addRegions e tipi servicesRegion modo da poter fare:

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

Se Marionette ha un tipo di interfaccia per l'applicazione, si potrebbe anche estendere tale come la seguente:

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

Per questo esempio ho utilizzato una definizione ridotta di Marionetta BackBone.

Se si aggiungono molte proprietà dinamiche a un oggetto, è consigliabile lasciare le cose dinamiche anziché tentare di creare dichiarazioni o interfacce per tutti, in particolare come il sovraccarico di mantenere le dichiarazioni aggiornate con nuove le proprietà rispetto ai vantaggi di avere una digitazione statica su proprietà effettivamente dinamiche non è un costo che pagherei.

In questo esempio, l'accesso alla proprietà utilizzando la sintassi parentesi quadra significa che passa il controllo del tipo senza la necessità di una dichiarazione. Il bit importante è sull'ultima riga.

È possibile eseguire il test su 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

In realtà, TypeScript e Marionette si inseriscono perfettamente nel guanto.
La chiave qui è pensare in termini di classi anziché di proprietà dinamiche. Con questo in mente, il codice diventa di sopra di questo:

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

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

Aggiornamento: parte 1 di un articolo del blog
ho appena postato su TypeScript: Using Backbone.Marionette and RESTful WebAPI.

Problemi correlati