2012-10-18 8 views
8

Durante la scrittura di questo codice TypeScript mi ​​ha sorpreso vedere che il compilatore TypeScript non mi avvisa quando converto da stringa a numero.Perché TypeScript consente la conversione da stringa a numero senza avviso

var a = new string[]; 
a.push('a') 
a.push('b') 
a.push('c') 

var i:string; 
for (i in a) { 
    var c : number = a[i]; <---- Here a is string[] but I assign it to c which is number 
    alert(c.toString()) 
} 

risposta

18

Risposta breve: a[i] è di tipo any, non string.

Risposta lunga: a è di tipo string[]. In TypeScript, gli oggetti di tipo T[] che sono indicizzati da un number generano un valore di tipo T, ma indicizzandoli con un risultato string in un any. I valori di tipo any possono essere convertiti liberamente in qualsiasi altro tipo.

Perché?

Quando si indicizza un array con una stringa, il compilatore non ha semplicemente la capacità di prevedere cosa accadrà e si è bloccati con any. Considerate:

// Elsewhere... 
Array.prototype.danger = 35; 

// Meanwhile, back at the ranch: 
var a = [ 'z' ]; 

var i: string; 
for (i in a) { 
    var x = a[i]; // i = 'danger', a[i] = 35... 
} 

Se siete veramente sicuri che nessuno sta per essere pasticciare con il vostro oggetto, o si sta prendendo indici da un insieme noto di sicurezza dei valori di stringa, è possibile scrivere un tipo di indicizzazione. Nel caso in cui stai indicizzando con una stringa, probabilmente stai meglio usando un oggetto piuttosto che un array:

var a: {[s: string]: string; } = {}; 
a['hello'] = 'world'; 
var i:string; 
for (i in a) { 
    var c : number = a[i]; // Issues an error 
} 
+1

+1 - spiegazione completa. – Fenton

+4

Non utilizzare "per ... in" in questo modo. Ecma "for ... in" non è la stessa di foreach in C#. Dovresti controllare ogni iterazione se è proprietà ereditata (come da prototipo) o meno. –