2013-09-23 19 views

risposta

109

oggetto è più restrittiva rispetto a qualsiasi. Cioè:

interface MyInterface { 

    b: Object; 
} 

var foo = (a : MyInterface) => alert(a.b.nomethod()); 

Will non compilare perché Object non hanno una funzione nomethod(). Se si utilizza any nell'interfaccia invece di Object, verrà compilato.

Quindi, in breve, any può essere qualsiasi cosa (è possibile chiamare qualsiasi metodo ecc. Senza errori di compilazione). Se si utilizza esplicitamente lo Object, sarà possibile utilizzare solo i metodi ecc. Definiti nella classe Object.

+0

Sto lavorando con un file di definizione esterno che utilizza Object. C'è un modo per estenderlo in modo che il compilatore accetti le stringhe? – Jay

12

oggetto sembra essere una dichiarazione più specifica di qualsiasi. Dalla dattiloscritto spec (punto 3):

Tutti i tipi a macchina sono sottotipi di un solo tipo superiore denominata Qualsiasi tipo. La parola chiave any fa riferimento a questo tipo. Il tipo Any è il un tipo che può rappresentare qualsiasi valore JavaScript senza vincoli. Tutti gli altri tipi sono classificati come tipi primitivi, tipi di oggetto o parametri di tipo . Questi tipi introducono vari vincoli statici su loro valori.

anche:

Il Qualsiasi tipo è usato 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, è possibile accedere alle proprietà di qualsiasi nome tramite un valore Qualsiasi e Qualsiasi valore può essere chiamato come funzione o costruttori con qualsiasi elenco di argomenti.

Gli oggetti non consentono la stessa flessibilità.

Ad 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'. 
+1

Buona risposta, potrebbe essere meglio per mostrare la mancanza di flessibilità – basarat

+2

cura. Forse non è il miglior emendamento, ma è almeno veritiero. :) –

22

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

Object si riferisce al tipo JavaScript object. Comunemente utilizzato come {} o talvolta new Object. La maggior parte delle cose nello javascript sono compatibili con il tipo di dati dell'oggetto che ereditano da esso. Ma any è TypeScript specifico e compatibile con tutto in entrambe le direzioni (non basato sull'eredità). 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; 
13

Contrariamente a.NET dove tutti i tipi derivano da un "oggetto", 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.

145

Bit vecchio, ma non fa male aggiungere alcune note.

quando si scrive qualcosa di simile

var a: any; 
var b: Object; 
var c: {}; 
  • un ha alcuna interfaccia, può essere qualsiasi cosa, il compilatore non sa nulla dei suoi membri il controllo di tipo talmente minima è fatto quando si accede/assegnazione sia per stesso e i suoi membri. Fondamentalmente, stai dicendo al compilatore di "indietro, so cosa sto facendo, quindi fidati di me";
  • b ha l'interfaccia Oggetto, quindi SOLO i membri definiti in tale 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 c è uguale a b perché ha la stessa interfaccia: l'interfaccia Oggetto.

Ed è per questo

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 

Così sia Object e {} sono equivalenti per dattiloscritto. Non vedo nessuno davvero usarlo. Troppo restrittivo.

Se si dichiara funzioni come questi

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

con l'intenzione di accettare qualsiasi cosa per param (forse si sta andando a controllare i tipi di a run-time per decidere che cosa fare con esso), ricorda che

  • all'interno fa, il compilatore ti consente di fare quello che vuoi con param;
  • all'interno fb, il compilatore solo consente di accedere i membri di oggetto, e si finirà per avere a che fare un sacco di fusione di caratteri lì ...

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

Ovviamente, si applicano ancora le regole OO di successione, quindi se si desidera accettare le istanze di classi derivate e trattarli 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 qualsiasi.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.

UPDATE:

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

consideri funzioni definite come:

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

x avranno le stesse proprietà disponibili all'interno tutte queste funzioni, ma è un errore di tipo a chiamare d con qualsiasi cosa non primitiva:

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

Qualcuno sa * perché * ha deciso di aggiungere '{}' se avesse già 'Object'? (o viceversa, a seconda di quale è arrivato prima) Ci deve essere una leggera differenza, giusto? – CletusW

+2

'{}' è il modo normale per definire interfacce (in linea), solo che in questo caso si sta definendo un'interfaccia senza membri. La leggera differenza è ben spiegata nella risposta: "' {} 'estende' Object', come qualsiasi altra cosa in TypeScript ". – DanielM

+0

Voglio abbassare il tuo voto per la linea _Quindi, in fondo, quando non conosci il tipo, vai con 'any' e fai il controllo del tipo di runtime. Non usare' any', usa invece un'unione di i tipi che stai verificando: 'TypeA | InterfaceB | string'. Se hai anche un caso predefinito per un tipo sconosciuto, aggiungi "{}" o "Oggetto" al sindacato. – ILMTitan

0

Aggiungendo alla risposta di Alex e semplificandolo:

Gli oggetti sono più rigidi con il loro uso e quindi dà il p rogrammer più potenza di "valutazione" del tempo di compilazione e quindi in molti casi forniscono più "capacità di verifica" e potrebbero prevenire eventuali perdite, mentre ogni è un termine più generico e molti controlli di tempo di compilazione potrebbero quindi essere ignorati.

0

provare questo:

private a: Object<any> = {}; 

constructor() { 
    a.name = "foo"; 
} 
+0

Le risposte solo in codice sono scoraggiate perché non spiegano come risolvono il problema. Si prega di aggiornare la risposta per spiegare come questo migliora le altre risposte accettate e potenziate che questa domanda ha già. Inoltre, questa domanda ha 4 anni, i tuoi sforzi sarebbero più apprezzati dagli utenti che hanno domande senza risposta recenti. Si prega di rivedere [Come scrivere una buona risposta] (https://stackoverflow.com/help/how-to-answer). – FluffyKitten