number - TypeScript any vs Object
typescript object (7)
Añadiendo a la respuesta de Alex y simplificándola:
Los objetos son más estrictos con su uso y por lo tanto le dan al programador más poder de "evaluación" en tiempo de compilación y por lo tanto en muchos casos proporcionan más "capacidad de comprobación" y pueden evitar fugas, mientras que cualquiera es un término más genérico y mucho compilado las verificaciones de tiempo pueden ser ignoradas.
Estoy mirando el código TypeScript y noté que usan
interface Blablabla {
field: Object;
}
¿Cuál es el beneficio de usar Object vs any , como en
interface Blablabla {
field: any;
}
Contrariamente a .NET donde todos los tipos se derivan de un "objeto", en TypeScript, todos los tipos derivan de "any". Solo quería agregar esta comparación, ya que creo que será una más común a medida que más desarrolladores .NET prueben TypeScript.
El objeto es más restrictivo que cualquier otro. Es decir:
interface MyInterface {
b: Object;
}
var foo = (a : MyInterface) => alert(a.b.nomethod());
No se compilará porque Object
no tiene una función nomethod()
. Si usa any
en la interfaz en lugar de Object
, compilaría.
En resumen, any
puede ser cualquier cosa (puede llamar a cualquier método, etc. sin errores de compilación). Si usa Object
explícitamente, solo podrá usar los métodos, etc., que están definidos en la clase Object
.
El objeto parece ser una declaración más específica que cualquiera. De la especificación de TypeScript (sección 3):
Todos los tipos en TypeScript son subtipos de un solo tipo superior llamado Any type. La palabra clave any hace referencia a este tipo. El tipo Cualquier es el tipo que puede representar cualquier valor de JavaScript sin restricciones. Todos los demás tipos se clasifican como tipos primitivos, tipos de objeto o parámetros de tipo. Estos tipos presentan diversas restricciones estáticas en sus valores.
También:
El tipo Any se usa para representar cualquier valor de JavaScript. Un valor de Cualquier tipo admite las mismas operaciones que un valor en JavaScript y se realiza una comprobación mínima del tipo estático para las operaciones en Cualquier valor. Específicamente, se puede acceder a las propiedades de cualquier nombre a través de un valor Cualquier y Se pueden llamar a cualquier valor como funciones o constructores con cualquier lista de argumentos.
Los objetos no permiten la misma flexibilidad.
Por ejemplo:
var myAny : any;
myAny.Something(); // no problemo
var myObject : Object;
myObject.Something(); // Error: The property ''Something'' does not exist on value of type ''Object''.
Un poco viejo, pero no duele agregar algunas notas.
Cuando escribes algo como esto
var a: any;
var b: Object;
var c: {};
- a no tiene interfaz, puede ser cualquier cosa, el compilador no sabe nada acerca de sus miembros, por lo que se realiza una verificación de tipo mínima al acceder / asignar tanto a sí mismo como a sus miembros. Básicamente, le estás diciendo al compilador que " retroceda, sé lo que estoy haciendo, así que confía en mí ";
- b tiene la interfaz Object, por lo que SOLAMENTE los miembros definidos en esa interfaz están disponibles para b . Sigue siendo JavaScript, por lo que todo se extiende a Object;
- c extiende Object, como cualquier otra cosa en TypeScript, pero no agrega miembros. Como la compatibilidad de tipos en TypeScript se basa en el subtipado estructural, no en el subtipaje nominal, c termina siendo el mismo que b porque tienen la misma interfaz: la interfaz Object.
Y es por eso
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
y por qué
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
Por lo tanto, tanto Object
como {}
son equivalentes para TypeScript. No veo a nadie realmente usándolo. Demasiado restrictivo.
Si declaras funciones como estas
function fa(param: any): void {}
function fb(param: Object): void {}
con la intención de aceptar cualquier cosa para param (quizás va a verificar tipos en tiempo de ejecución para decidir qué hacer con él), recuerde que
- Dentro de fa , el compilador te permitirá hacer lo que quieras con param ;
- dentro de fb , el compilador solo te permitirá acceder a los miembros de Object, y terminarás teniendo que hacer una gran cantidad de typecasting allí ...
Entonces, básicamente, cuando no se conoce el tipo, vaya con any y haga la comprobación de tipo en tiempo de ejecución.
Obviamente, las reglas de herencia OO todavía se aplican, por lo que si desea aceptar instancias de clases derivadas y tratarlas en función de su tipo base, como en
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..
el tipo base es la forma de hacerlo, no cualquier . Pero eso es OO, fuera del alcance, solo quería aclarar que cualquiera debería usarse solo cuando no sabes lo que está por venir, y para cualquier otra cosa debes anotar el tipo correcto.
ACTUALIZAR:
Typescript 2.2 agregó un tipo de object
, que especifica que un valor no es primitivo: (es decir, no es un number
, string
, boolean
, symbol
, undefined
o null
).
Considere funciones definidas como:
function b(x: Object) {}
function c(x: {}) {}
function d(x: object) {}
x
tendrá las mismas propiedades disponibles en todas estas funciones, pero es un tipo de error llamar a d
con cualquier cosa que no sea primitiva:
b("foo"); //Okay
c("foo"); //Okay
d("foo"); //Error: "foo" is a primitive
prueba esto :
private a: Object<any> = {};
constructor() {
a.name = "foo";
}
any
es algo específico de TypeScript explicado bastante bien por la respuesta de Alex.
Object
refiere al tipo de object
JavaScript. Comúnmente utilizado como {}
o, a veces, new Object
. La mayoría de las cosas en javascript son compatibles con el tipo de datos del objeto, ya que heredan de él. Pero any
es específico de TypeScript y es compatible con todo en ambas direcciones (no basado en la herencia). p.ej :
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;