'any' vs 'Object'


209

Ich schaue auf TypeScript-Code und habe festgestellt, dass sie Folgendes verwenden:

interface Blablabla {

   field: Object;

}

Was ist der Vorteil der Verwendung von Objectvs any, wie in:

interface Blablabla {

  field: any;

}

Antworten:


202

Objectist restriktiver als any. Beispielsweise:

let a: any;
let b: Object;

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

Die ObjectKlasse hat keine nomethod()Funktion, daher generiert der Transpiler einen Fehler, der Ihnen genau das sagt. Wenn Sie anystattdessen verwenden, sagen Sie dem Transpiler im Grunde, dass alles möglich ist, und geben keine Informationen darüber an, was darin gespeichert ist a- es kann alles sein! Und deshalb können Sie mit dem Transpiler mit etwas, das als definiert ist, tun, was Sie wollen any.

Also kurz gesagt

  • any kann alles sein (Sie können jede Methode usw. ohne Kompilierungsfehler aufrufen)
  • Objectmacht die in der ObjectKlasse definierten Funktionen und Eigenschaften verfügbar .

283

Etwas alt, aber es tut nicht weh, ein paar Notizen hinzuzufügen.

Wenn du so etwas schreibst

let a: any;
let b: Object;
let c: {};
  • a hat keine Schnittstelle, es kann alles sein, der Compiler weiß nichts über seine Mitglieder, so dass keine Typprüfung durchgeführt wird, wenn auf ihn und seine Mitglieder zugegriffen wird. Grundsätzlich sagen Sie dem Compiler, er solle " zurücktreten, ich weiß, was ich tue, also vertrauen Sie mir einfach ".
  • b hat die Objektschnittstelle, so dass NUR die in dieser Schnittstelle definierten Mitglieder für b verfügbar sind . Es ist immer noch JavaScript, also erweitert alles Object;
  • c erweitert Object wie alles andere in TypeScript, fügt jedoch keine Mitglieder hinzu. Da die Typkompatibilität in TypeScript auf der strukturellen Untertypisierung und nicht auf der nominalen Untertypisierung basiert, ist c mit b identisch, da sie dieselbe Schnittstelle haben: die Objektschnittstelle.

Und deshalb

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

und warum

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

Also Objectund {}sind Äquivalente in TypeScript.

Wenn Sie Funktionen wie diese deklarieren

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

Denken Sie daran, wenn Sie beabsichtigen, irgendetwas für param zu akzeptieren (möglicherweise überprüfen Sie zur Laufzeit die Typen, um zu entscheiden, was damit geschehen soll)

  • In fa lässt der Compiler Sie mit param tun, was Sie wollen .
  • In fb können Sie mit dem Compiler nur auf die Mitglieder von Object verweisen .

Es ist jedoch anzumerken, dass, wenn param mehrere bekannte Typen akzeptieren soll, ein besserer Ansatz darin besteht, sie unter Verwendung von Unionstypen zu deklarieren, wie in

function fc(param: string|number): void {}

Offensichtlich gelten weiterhin OO-Vererbungsregeln. Wenn Sie also Instanzen abgeleiteter Klassen akzeptieren und sie basierend auf ihrem Basistyp wie in behandeln möchten

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

Der Basistyp ist der Weg, nicht irgendein . Aber das ist OO, aus dem Rahmen heraus, ich wollte nur klarstellen, dass jedes nur verwendet werden sollte, wenn Sie nicht wissen, was kommt, und für alles andere sollten Sie den richtigen Typ mit Anmerkungen versehen.

AKTUALISIEREN:

Maschinenschrift 2.2 einen zusätzlichen objectTyp, der angibt , dass ein Wert , ein nicht-primitive ist: (dh kein number, string, boolean, symbol, undefined, oder null).

Betrachten Sie Funktionen, die wie folgt definiert sind:

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

xhat in all diesen Funktionen die gleichen verfügbaren Eigenschaften, aber es ist ein Typfehler, den man dmit einem Grundelement aufruft:

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

2
Weiß jemand, warum sie beschlossen haben, {}dann hinzuzufügen, wenn sie bereits hatten Object? (oder umgekehrt, je nachdem, was zuerst kam) Es muss einen kleinen Unterschied geben, oder?
CletusW

4
{}ist die normale Methode zum Definieren von (Inline-) Schnittstellen, nur dass Sie in diesem Fall eine Schnittstelle ohne Mitglieder definieren. Der geringfügige Unterschied wird in der Antwort gut erklärt: " {}Erweitert Objectsich wie alles andere in TypeScript".
DanielM

7
Ich möchte Sie für die Zeile abstimmen. Wenn Sie also den Typ nicht kennen, gehen Sie mit anyund führen Sie zur Laufzeit eine Typprüfung durch. Verwenden Sie nicht any, sondern eine Vereinigung der Typen, gegen die Sie prüfen : TypeA|InterfaceB|string. Wenn Sie auch einen Standardfall für einen unbekannten Typ haben, fügen Sie entweder {}oder Objectzur Union hinzu.
ILMTitan

Typoskript-Dokumente sind manchmal verwirrend, zum Beispiel But variables of type Object only allow you to assign any value to them - you can’t call arbitrary methods on them, even ones that actually exist:habe ich gedacht, dass sogar das Anrufen toStringnicht erlaubt ist , obwohl ich denke, dass sie exist at runtimenach dem Lesen Ihrer Antwort sagen sollen .
Olga

24

any ist etwas Spezielles für TypeScript und wird durch die Antwort von Alex recht gut erklärt.

Objectbezieht sich auf den JavaScript- objectTyp. Wird häufig als {}oder manchmal verwendet new Object. Die meisten Dinge in Javascript sind mit dem Objektdatentyp kompatibel, da sie von ihm erben. Aber anyist Typoskript spezifisch und kompatibel mit allem , was in beiden Richtungen (keine Vererbung basiert). z.B :

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;  

1
Ihre Antwort ist ziemlich vage und gemischt Objectund es objectgibt verschiedene Typen in TypeScript.
M93a

@ m93a: Kannst du den Unterschied zwischen Objectund objectin TS näher erläutern ?
Alexander Abakumov

4
Dies ist wahrscheinlich die beste Quelle, um den Unterschied zu lernen. Der Hauptpunkt ist, dass dies objectein Typ für alles ist, was nicht primitiv ist, während Objectes sich um eine Schnittstelle handelt, die allgemeine Dinge wie toStringund so enthält. Die Nummer 42wäre eine Objectaber keine object.
M93a

20

Im Gegensatz zu .NET, wo alle Typen von einem "Objekt" abgeleitet sind, stammen in TypeScript alle Typen von "any". Ich wollte diesen Vergleich nur hinzufügen, da ich denke, dass er häufig verwendet wird, wenn mehr .NET-Entwickler TypeScript ausprobieren.


16

Das Objekt scheint eine spezifischere Deklaration zu sein als jede andere. Aus der TypeScript-Spezifikation (Abschnitt 3):

Alle Typen in TypeScript sind Untertypen eines einzelnen Top-Typs, der als Any-Typ bezeichnet wird. Das Schlüsselwort any verweist auf diesen Typ. Der Any-Typ ist der Typ, der jeden JavaScript-Wert ohne Einschränkungen darstellen kann. Alle anderen Typen werden als primitive Typen, Objekttypen oder Typparameter kategorisiert. Diese Typen führen verschiedene statische Einschränkungen für ihre Werte ein.

Ebenfalls:

Der Any-Typ wird verwendet, um einen beliebigen JavaScript-Wert darzustellen. Ein Wert vom Typ Any unterstützt dieselben Operationen wie ein Wert in JavaScript, und für Operationen mit Any-Werten wird eine minimale statische Typprüfung durchgeführt. Insbesondere kann auf Eigenschaften eines beliebigen Namens über einen beliebigen Wert zugegriffen werden, und auf beliebige Werte können als Funktionen oder Konstruktoren mit einer beliebigen Argumentliste aufgerufen werden.

Objekte erlauben nicht die gleiche Flexibilität.

Beispielsweise:

var myAny : any;

myAny.Something(); // no problemo

var myObject : Object;

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

0

Alex 'Antwort ergänzen und vereinfachen:

Objekte sind strenger in ihrer Verwendung und geben dem Programmierer daher mehr Kompilierungszeit "Evaluierungs" -Leistung und bieten daher in vielen Fällen mehr "Überprüfungsmöglichkeiten" und könnten Leckagen verhindern, während jeder ein allgemeinerer Begriff und viel Kompilieren ist Zeitprüfungen können daher ignoriert werden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.