2015-08-05 22 views
8

Quando si utilizza dattiloscritto un'interfaccia dichiarata potrebbe essere la seguente:Come ridurre javascript oggetto per contenere solo oggetti di interfaccia

interface MyInterface { 
    test: string; 
} 

E un'implementazione con la proprietà in più potrebbe essere simile a questo:

class MyTest implements MyInterface { 
    test: string; 
    newTest: string; 
} 

Esempio (qui la variabile 'ridotta' contiene ancora la proprietà 'newTest'):

var test: MyTest = {test: "hello", newTest: "world"} 

var reduced: MyInterface = test; // something clever is needed 

Domanda

In modo generale, come si può fare la variabile 'ridotto' per contenere solo le proprietà dichiarate nell'interfaccia 'MyInterface'.

Perché

Il problema si verifica quando si cerca di utilizzare la variabile 'ridotta' con angular.toJson prima di inviarlo a un servizio di riposo - il metodo toJSON trasforma la variabile Newtest, anche se non è accessibile sul istanza durante la compilazione, e questo rende il servizio di riposo non accetta il json poiché ha proprietà che non dovrebbero essere lì.

risposta

0

Possibilmente un duplicato di:

TypeScript or JavaScript type casting

devi "lanciare" il tuo valore a un tipo diverso.

alcuni buoni esempi sono anche qui: http://blogs.microsoft.co.il/gilf/2013/01/18/using-casting-in-typescript/

this.span = <HTMLSpanElement>document.createElement('span'); 

speranza che questo ha aiutato?

+1

No, mi dispiace, non aiuta. E non riesco a vedere come potrebbe essere un duplicato neanche. Grazie per aver risposto :) :) –

+0

È un duplicato perché il valore "ridotto" di cui parli si chiama casting. –

+1

Bene, il problema che ho non è come lanciare una variabile: funziona bene. Il problema è che l'istanza castata contiene ancora le proprietà extra. La domanda che hai collegato non interessa a questo e non la richiede neanche. –

1

Nel tuo esempio Newtest proprietà non sarà accessibile attraverso il ridotto variabile, in modo che l'obiettivo di utilizzare i tipi. Il dattiloscritto porta il controllo del tipo, ma non manipola le proprietà dell'oggetto.

+0

Il nostro problema è che proviamo ad usare la variabile 'ridotta' con angular.toJson prima di inviarlo a un servizio di riposo - e toJson trasforma anche la variabile newTest anche se non è accessibile dall'istanza. –

1

Si sta tentando di impostare/assegnare solo le proprietà elencate solo sull'interfaccia? Funzionalità del genere non è disponibile in TypeScript, ma è molto semplice scrivere una funzione per eseguire il comportamento che stai cercando.

interface IPerson { 
 
    name: string; 
 
} 
 

 
class Person implements IPerson { 
 
\t name: string = ''; 
 
} 
 
class Staff implements IPerson { 
 
\t name: string = ''; 
 
    position: string = ''; 
 
} 
 

 
var jimStaff: Staff = { 
 
    name: 'Jim', 
 
    position: 'Programmer' 
 
}; 
 

 
var jim: Person = new Person(); 
 
limitedAssign(jimStaff, jim); 
 
console.log(jim); 
 

 
function limitedAssign<T,S>(source: T, destination: S): void { 
 
    for (var prop in destination) { 
 
     if (source[prop] && destination.hasOwnProperty(prop)) { 
 
      destination[prop] = source[prop]; 
 
     } 
 
    } 
 
}

+1

Questo è qualcosa di simile a quello che sto cercando. Non riesco a farlo funzionare comunque. Credo che sia perché le proprietà su 'jim' non sono inizializzate e non trovano proprietà da scorrere. Inoltre, se fosse un modo per saltare un 'Person' di classe e semplicemente scorrere le proprietà direttamente da IPerson, sarebbe perfetto. –

+0

@TomasF Ho avuto lo stesso problema e capito. Vedi https://github.com/Microsoft/TypeScript/issues/6515 poiché il JS sottostante non ha proprietà predefinite, quindi il ciclo 'for' non ha proprietà per iterare sopra. La soluzione è aggiungere valori predefiniti a ogni proprietà come 'name: string = '';' – ubershmekel

0

In modo generale, come si può fare la variabile 'ridotto' per contenere solo le proprietà dichiarate nell'interfaccia 'MyInterface'.

Dal dattiloscritto è strutturale questo significa che tutto ciò che contiene le informazioni pertinenti tipo compatibile e quindi assegnabili.

Detto questo, TypeScript 1.6 otterrà un concetto chiamato freshness.Questo renderà più facile per la cattura chiare errori di battitura (nota di freschezza vale solo per opporsi letterali):

// ERROR : `newText` does not exist on `MyInterface` 
var reduced: MyInterface = {test: "hello", newTest: "world"}; 
0

TS 2.1 è diffuso oggetto e di riposo, quindi è possibile ora:

var my: MyTest = {test: "hello", newTest: "world"} 

var { test, ...reduced } = my; 

Dopo quello ridotto conterrà tutte le proprietà ad eccezione di "test".

+0

Potresti spiegare, cosa intendi per Object Spread and Rest? Intendi i tripli punti? ... giusto? –

+0

Sì. La diffusione degli oggetti consente di esplodere le proprietà, Rest per tagliare le proprietà. –

Problemi correlati