TypeScript any vs Object

Sto guardando il codice TypeScript e ho notato che usano

interface Blablabla { field: Object; } 

Qual è il vantaggio dell’utilizzo di Object vs any , come in

 interface Blablabla { field: any; } 

L’object è più restrittivo di qualsiasi altro. Questo è:

 interface MyInterface { b: Object; } var foo = (a : MyInterface) => alert(abnomethod()); 

Non verrà compilato perché Object non ha una funzione nomethod() . Se ne usi any nell’interfaccia invece di Object , si compilerebbe.

Quindi, in breve, any può essere qualsiasi cosa (puoi chiamare qualsiasi metodo ecc. Senza errori di compilazione). Se si utilizza in modo esplicito l’ Object , sarà ansible utilizzare solo i metodi ecc. Definiti nella class Object .

Un po ‘vecchio, ma non fa male aggiungere alcune note.

Quando scrivi qualcosa come questo

 var a: any; var b: Object; var c: {}; 
  • non ha un’interfaccia, può essere qualsiasi cosa, il compilatore non sa nulla dei suoi membri, quindi viene eseguito un minimo controllo dei tipi quando si accede / si assegna a se stesso e ai suoi membri. Fondamentalmente, stai dicendo al compilatore di “fare marcia indietro, so cosa sto facendo, quindi fidati di me “;
  • b ha l’interfaccia Object, quindi SOLO i membri definiti in quell’interfaccia sono disponibili per b . È ancora JavaScript, quindi tutto estende Object;
  • c estende Object, come qualsiasi altra cosa in TypeScript, ma non aggiunge membri. Poiché la compatibilità del tipo in TypeScript si basa sulla sottotipizzazione strutturale, non sulla sottotipizzazione nominale, c risulta essere uguale a b perché hanno la stessa interfaccia: l’interfaccia Oggetto.

Ed ecco perché

 a.doSomething(); // Ok: the compiler trusts you on that b.doSomething(); // Error: Object has no doSomething member c.doSomething(); // Error: c neither has doSomething nor inherits it from Object 

e perché

 a.toString(); // Ok: whatever, dude, have it your way b.toString(); // Ok: toString is defined in Object c.toString(); // Ok: c inherits toString from Object 

Quindi sia Object che {} sono equivalenti per TypeScript. Non vedo nessuno davvero usarlo. Troppo restrittivo.

Se dichiari funzioni come queste

 function fa(param: any): void {} function fb(param: Object): void {} 

con l’intenzione di accettare qualsiasi cosa per param (forse stai andando a controllare i tipi in fase di esecuzione per decidere cosa fare con esso), ricorda che

  • dentro fa , il compilatore ti permetterà di fare tutto ciò che vuoi con param ;
  • all’interno di fb , il compilatore ti permetterà solo di accedere ai membri di Object, e finirai per dover fare un sacco di typecasting lì …

Quindi, in sostanza, quando non si conosce il tipo, andare con qualsiasi e fare il controllo del tipo di runtime.

Ovviamente, le regole di ereditarietà OO si applicano ancora, quindi se si desidera accettare istanze di classi derivate e trattarle in base al loro tipo di base, come in

 interface IPerson { gender: string; } class Person implements IPerson { gender: string; } class Teacher extends Person {} function func(person: IPerson): void { console.log(person.gender); } func(new Person()); // Ok func(new Teacher()); // Ok func({gender: 'male'}); // Ok func({name: 'male'}); // Error: no gender.. 

il tipo di base è il modo per farlo, non nessuno . Ma questo è OO, fuori ambito, volevo solo chiarire che qualsiasi dovrebbe essere usato solo quando non sai che cosa sta arrivando, e per qualsiasi altra cosa dovresti annotare il tipo corretto.

AGGIORNARE:

Typescript 2.2 ha aggiunto un tipo di object , che specifica che un valore è un non-primitivo: (cioè non un number , una string , un boolean , un symbol , undefined o null ).

Considera le funzioni definite come:

 function b(x: Object) {} function c(x: {}) {} function d(x: object) {} 

x avrà le stesse proprietà disponibili in tutte queste funzioni, ma è un errore di tipo chiamare d con qualcosa di non primitivo:

 b("foo"); //Okay c("foo"); //Okay d("foo"); //Error: "foo" is a primitive 

any è specifico per TypeScript è spiegato abbastanza bene dalla risposta di alex.

Object riferisce al tipo di object JavaScript. Comunemente usato come {} o talvolta come new Object . La maggior parte delle cose in javascript sono compatibili con il tipo di dati dell’object che ereditano da esso. Ma any è specifico per TypeScript e compatibile con any cosa in entrambe le direzioni (non basata sull’ereditarietà). per esempio :

 var foo:Object; var bar:any; var num:number; foo = num; // Not an error num = foo; // ERROR // Any is compatible both ways bar = num; num = bar; 

Contrariamente a .NET, in cui tutti i tipi derivano da un “object”, in TypeScript, tutti i tipi derivano da “any”. Volevo solo aggiungere questo confronto, perché penso che sarà comune, dato che più sviluppatori .NET danno a TypeScript una prova.

L’object sembra essere una dichiarazione più specifica di qualsiasi. Dalle specifiche TypeScript (sezione 3):

Tutti i tipi in TypeScript sono sottotipi di un singolo tipo superiore chiamato Qualsiasi tipo. La parola chiave any fa riferimento a questo tipo. Il tipo Qualsiasi è l’unico tipo che può rappresentare qualsiasi valore JavaScript senza vincoli. Tutti gli altri tipi sono classificati come tipi primitivi, tipi di object o parametri di tipo. Questi tipi introducono vari vincoli statici sui loro valori.

Anche:

Il tipo Any viene utilizzato per rappresentare qualsiasi valore JavaScript. Un valore di Qualsiasi tipo supporta le stesse operazioni di un valore in JavaScript e il controllo di tipo statico minimo viene eseguito per le operazioni su Qualsiasi valore. Nello specifico, è ansible accedere alle proprietà di qualsiasi nome tramite un valore Qualsiasi e Qualsiasi valore può essere chiamato come funzione o costruttore con qualsiasi elenco di argomenti.

Gli oggetti non consentono la stessa flessibilità.

Per esempio:

 var myAny : any; myAny.Something(); // no problemo var myObject : Object; myObject.Something(); // Error: The property 'Something' does not exist on value of type 'Object'. 

Aggiungendo la risposta di Alex e semplificandolo:

Gli oggetti sono più rigidi con il loro uso e quindi danno al programmatore più potere di “valutazione” del tempo di compilazione e quindi in molti casi forniscono più “capacità di controllo” e possono prevenire eventuali perdite, mentre qualsiasi è un termine più generico e molto compilativo i controlli orari potrebbero quindi essere ignorati.

prova questo :

 private a: Object = {}; constructor() { a.name = "foo"; }