web-dev-qa-db-fra.com

'n'importe quel' vs 'objet'

Je regarde le code de TypeScript et ai remarqué qu'ils utilisent:

interface Blablabla {

   field: Object;

}

Quel est l'avantage d'utiliser Object contre any, comme dans:

interface Blablabla {

  field: any;

}
180
Olivier Refalo

Object est plus restrictif que any. Par exemple:

let a: any;
let b: Object;

a.nomethod(); // Transpiles just fine
b.nomethod(); // Error: Property 'nomethod' does not exist on type 'Object'.

La classe Object n'a pas de fonction nomethod(), le transpiler générera donc une erreur vous indiquant exactement cela. Si vous utilisez any à la place, vous dites au transpiler que quelque chose se passe, vous ne fournissez aucune information sur ce qui est stocké dans a - cela peut être n'importe quoi! Et donc, le transpiler vous permettra de faire ce que vous voulez avec quelque chose défini comme any.

Donc bref

  • any peut être n'importe quoi (vous pouvez appeler n'importe quelle méthode, etc. sans erreur de compilation)
  • Object expose les fonctions et propriétés définies dans la classe Object.
179
Nypan

Un peu vieux, mais ça ne fait pas de mal d'ajouter quelques notes.

Quand tu écris quelque chose comme ça

var a: any;
var b: Object;
var c: {};
  • a n'a pas d'interface, il peut être n'importe quoi, le compilateur ne sait rien de ses membres. Un contrôle de type minimal est donc effectué lors de l'accès/l'attribution à lui-même et à son membres. En gros, vous dites au compilateur de "reculer, je sais ce que je fais, alors faites-moi confiance";
  • b a l'interface Object, seuls les membres définis dans cette interface sont disponibles pour b . C'est toujours JavaScript, donc tout s'étend d'objet;
  • c étend Object, comme n'importe quoi d'autre dans TypeScript, mais n'ajoute aucun membre. Étant donné que la compatibilité des types dans TypeScript est basée sur le sous-typage structurel et non sur le sous-typage nominal, c finit par être identique à b car ils ont la même interface: l'interface Object.

Et c'est pourquoi

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

et pourquoi

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

Donc, Object et {} sont équivalents pour TypeScript. Je ne vois personne l'utilisant vraiment. Trop restrictif.

Si vous déclarez des fonctions comme celles-ci

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

avec l'intention d'accepter n'importe quoi pour param (peut-être que vous allez vérifier les types au moment de l'exécution pour décider quoi faire avec), souvenez-vous que

  • dans fa , le compilateur vous permettra de faire ce que vous voulez avec param ;
  • dans fb , le compilateur ne vous laissera que accéder aux membres de Object, et vous finirez par avoir à faire beaucoup de transtypages là-bas ...

Donc, si vous ne connaissez pas le type, optez pour any et effectuez une vérification du type à l'exécution.

Bien entendu, OO _ règles d'héritage s'appliquent toujours. Par conséquent, si vous souhaitez accepter des instances de classes dérivées et les traiter en fonction de leur type de base, comme dans

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..

le type de base est le moyen de le faire, pas aucun . Mais c’est hors de propos, je voulais juste préciser que n’importe lequel ne devrait être utilisé que lorsque vous ne savez pas ce qui va arriver, et pour toute autre chose vous devriez annoter le type correct.

MISE À JOUR:

TypeScript 2.2 ajouté un type object, qui spécifie qu'une valeur est une non primitive: (c'est-à-dire pas un number, string, boolean , symbol, undefined ou null).

Considérons les fonctions définies comme:

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

x aura les mêmes propriétés disponibles dans toutes ces fonctions, mais c'est une erreur de type d'appeler d avec quelque chose de non primitif:

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

any quelque chose de spécifique à TypeScript est très bien expliqué par la réponse de alex.

Object fait référence au type JavaScript object. Couramment utilisé comme {} ou parfois new Object. La plupart des éléments de javascript sont compatibles avec le type de données d'objet car ils en héritent. Mais any est TypeScript spécifique et compatible avec tout ce qui se trouve dans les deux sens (non basé sur l'héritage). par exemple. :

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;  
23
basarat

Contrairement à .NET où tous les types dérivent d'un "objet", dans TypeScript, tous les types dérivent de "tout". Je voulais juste ajouter cette comparaison, car je pense que ce sera une comparaison courante à mesure que davantage de développeurs .NET donneront leur chance à TypeScript.

17
yellowbrickcode

L'objet semble être une déclaration plus spécifique que tout. A partir de la spécification TypeScript (section 3):

Tous les types dans TypeScript sont des sous-types d'un type supérieur unique appelé type Any. Le mot clé any fait référence à ce type. Le type Any est le type qui peut représenter n'importe quelle valeur JavaScript sans contrainte. Tous les autres types sont classés en types primitifs, types d'objet ou paramètres de type. Ces types introduisent diverses contraintes statiques sur leurs valeurs.

Aussi:

Le type Tout est utilisé pour représenter toute valeur JavaScript. Une valeur de type Any prend en charge les mêmes opérations qu'une valeur en JavaScript et une vérification de type statique minimale est effectuée pour les opérations sur des valeurs Any. Plus précisément, il est possible d'accéder aux propriétés de n'importe quel nom via une valeur Any et des valeurs Any peuvent être appelées en tant que fonctions ou constructeurs avec une liste d'arguments quelconque.

Les objets ne permettent pas la même flexibilité.

Par exemple:

var myAny : any;

myAny.Something(); // no problemo

var myObject : Object;

myObject.Something(); // Error: The property 'Something' does not exist on value of type 'Object'.
14
Alex Dresko

N'oubliez pas que vous ne devez jamais utiliser les types Number, String, Boolean ou Object conformément au TypeScript. Documentation

Ces types font référence à des objets en boîte non primitifs qui ne sont presque jamais utilisés correctement dans du code JavaScript.

0
Kamil

Ajoutant à la réponse d'Alex et simplifiant celle-ci:

Les objets sont plus stricts avec leur utilisation et donnent donc au programmeur plus de puissance "d'évaluation" lors de la compilation et fournissent donc dans de nombreux cas plus de "capacité de vérification" et peuvent empêcher toute fuite, alors que tout est un terme plus générique et beaucoup de compilation les contrôles horaires peuvent donc être ignorés.

0
kg11