2015-05-07 13 views
6

Se TypeScript è un superset di JavaScript rigido, perché la notazione dei punti su un oggetto arbitrario è errata? Ho il codice JS che voglio convertire su TS per una migliore sicurezza del tipo, ma tutti gli accessi tramite notazione a punti (ad esempio, myObj.thing) mi danno l'errore Property 'thing' does not exist on type '{}'.. Funziona correttamente quando uso la notazione della parentesi (ad esempio, myObj['thing']).Accesso agli oggetti TypeScript e dot-notation

Property does not exist on type

+3

Questo è un avvertimento, si deve ancora compilare, in modo da dattiloscritto è ancora un superset rigorosa di JS. Il motivo per cui ti avverte è che TypeScript è stato digitato, e il tipo di 'x' non specifica le proprietà' bar'. Puoi lanciare su 'any', applicare un'interfaccia che abbia' bar', o usare '[" bar "]'. –

+0

@Asad: l'errore mostrato e descritto viene segnalato come errore vero e proprio, non come avviso, e la mia build non riesce. Tuttavia, sono in grado di trasmettere a 'any' con successo. – user655321

+0

TypeScript è intenzionalmente più rigido di JavaScript, quindi avere JavaScript in JavaScript non significa necessariamente che il compilatore TypeScript sarà d'accordo. –

risposta

0

x non detiene alcuna proprietà denominata bar quindi è necessario crearlo all'interno dell'oggetto:

function foobar() { 
    var x = { 

     foo: 'foo', 
     bar: 'bar' 
    } 

    return x; 
} 

alert(foobar().bar); //returns bar 
+0

È [apparentemente legale JS] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects) da assegnare a una proprietà che non esiste ancora in un oggetto, quindi sembra strano che io non possa farlo in TS senza un cast per 'any' (come @Asad descrive sopra). – user655321

+0

Imparare qualcosa di nuovo ogni giorno ... Più modi diversi per dare una pelle a un gatto, credo. – mwilson

0

mwilson arrivati ​​prima ho potuto! ;)

Nel codice sopra, Typescript non è in grado di determinare che l'oggetto x esponga una proprietà denominata bar, quindi non può risolverlo durante la visualizzazione di Intellisense.

Invece, aggiungere foo, bar, ecc come proprietà dell'oggetto in sé:

var x = { 
    foo: "FOO", 
    bar: "BAR" 
}; 

Poi, quando si utilizza il Typescript Playground, sarete vedere il lavoro Intellisense come previsto:

enter image description here

HTH

5

so che dire che questo è strano, ma questo è uno o f i motivi principali per cui esiste TypeScript. Questo errore aiuta a prevenire l'impostazione accidentale o il recupero di proprietà inesistenti su un oggetto.

In questo momento, come il compilatore che si sta dicendo, la proprietà bar non esiste su x perché è stato implicitamente digitato per {} durante la scrittura var x = {};.

Si può dire al compilatore che x ha più di zero proprietà definendo in modo esplicito il tipo:

var x: { foo?: string; bar?: string; } = {}; 

Ora è possibile ottenere o impostare x.foo e x.bar senza il compilatore lamentarsi. Nella maggior parte dei casi, si potrebbe spostare questo in un'interfaccia in questo modo:

interface IFooBar { 
    foo?: string; 
    bar?: string; 
} 

var x: IFooBar = {}; 

x.foo = "asdf"; // ok 
x.test = "asdf"; // error, as it should be 

Alcune persone stanno suggerendo che lanci a any, ma non ottenere pigro. Si dovrebbe fare pieno uso del sistema di tipi fornito da TypeScript. In questo modo ti farai sicuramente risparmiare tempo mentre mantieni un'applicazione.

0

A causa della natura fortemente tipizzato di Carattere tipografico oggetto, è possibile utilizzare "qualsiasi" per farlo senza tipo:

var x: any = {}; 
x.bar = "bar"; /// ok 

Se quello di cui hai bisogno è di definire il tipo di proprietà letterali

var x: { [index: string]: TypeA } = {}; 

quindi x["bar"] ora può essere solo istanza di tipo A.

0

Personalmente preferisco specificare i tipi ogni volta che ne ho la possibilità.

Nota, è possibile creare un'istanza di questa variabile solo con {} se si definiscono i campi come facoltativi con l'operatore ?:.

let x: {foo?: string, bar?: string} = {}; 
x.foo = 'foo'; 
x.bar = 'bar'; 

Come altri hanno detto, se si prevede di utilizzare questo tipo più volte, probabilmente è meglio fare una classe esplicitamente per esso.

PS: è preferibile utilizzare let anziché var durante la programmazione in dattiloscritto. (Per esempio la portata di una dichiarazione var è un po 'eccentrico, rispetto ad un let che fa quello che ci si aspetta che faccia.)

Problemi correlati