2013-09-23 3 views

ответ

109

Объект является более жестким, чем любой. То есть:

interface MyInterface { 

    b: Object; 
} 

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

Будет не компиляции, потому что Object не имеет nomethod() функцию. Если вы используете any в интерфейсе вместо Object, он будет скомпилирован.

Итак, any может быть любым (вы можете вызвать любой метод и т. Д. На нем без ошибок компиляции). Если вы явно используете Object, вы сможете использовать только методы и т. Д., Которые определены в классе Object.

+0

Я работаю с файлом внешнего определения, который использует Object. Есть ли способ расширить его, чтобы компилятор принимал строки? – Jay

12

объекта, как представляется, более конкретное заявление, чем любое. Из машинописи спецификации (раздел 3):

Все типы в машинописном подтипы одного верхнего типа называется любого типа. Любое ключевое слово ссылается на этот тип. Любой тип - это один тип, который может представлять любое значение JavaScript без ограничений. Все остальные типы классифицируются как примитивные типы, типы объектов или параметры типа . Эти типы вводят различные статические ограничения на значения .

Также:

Любого типа используются для представления любого значения JavaScript. Значение Любой тип поддерживает те же операции, что и значение в JavaScript, и Минимальная статическая проверка типа выполняется для операций с любыми значениями . В частности, свойства любого имени могут быть доступны через a Любое значение и любые значения могут быть вызваны как функции или конструкторы с любым списком аргументов.

Объекты не допускают такой же гибкости.

Например:

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

Хороший ответ, может быть лучше, чтобы показать отсутствие гибкости – basarat

+2

отредактирован. Возможно, это не лучшая поправка, но, по крайней мере, правдивая. :) –

22

any - это нечто специфичное для TypeScript, которое объясняется ответом alex.

Object относится к JavaScript object. Обычно используется как {} или иногда new Object. Большинство вещей в javascript совместимы с типом данных объекта, поскольку они наследуют его. Но any - TypeScript специфичный и совместимый со всем в обоих направлениях (не основанный на наследовании). например :

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

Вопреки.NET, где все типы выводятся из «объекта», в TypeScript все типы выводятся из «любого». Я просто хотел добавить это сравнение, так как я думаю, что это будет распространено, поскольку разработчики .NET предлагают попробовать TypeScript.

145

Бит старый, но не помешает добавить некоторые заметки.

Когда вы пишете что-то вроде этого

var a: any; 
var b: Object; 
var c: {}; 
  • не имеет интерфейса, это может быть что угодно, компилятор ничего не знает о своих членах, так минимальна проверка типа делается при доступе к/назначению как для себя и своих членов. В принципе, вы говорите компилятору «отступать, я знаю, что я делаю, поэтому просто доверяйте мне»;
  • b имеет интерфейс Object, поэтому ТОЛЬКО члены, определенные в этом интерфейсе, доступны для b. Это все еще JavaScript, поэтому все расширяет Object;
  • c extends Object, как и все остальное в TypeScript, но не добавляет никаких членов. Поскольку совместимость типов в TypeScript основана на структурном подтипировании, а не на номинальном подтипировании, c заканчивается тем же, что и b, поскольку они имеют один и тот же интерфейс: интерфейс объекта.

И вот почему

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 

и почему

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 

Так как Object и {} эквивалентны машинопись. Я не вижу, чтобы кто-то действительно использовал его. Слишком ограничительный.

Если вы объявляете функции, как эти

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

с намерением принимать что-либо для PARAM (может быть, вы собираетесь проверять типы во время выполнения, чтобы решить, что с ним делать), помните, что

  • внутри фа, компилятор позволит вам делать все, что вы хотите с парами;
  • внутри фб, компилятор позволит только получить доступ к членам объекта, и вы будете в конечном итоге, сделать много типажей там ...

Таким образом, в основном, когда вы не делаете знаете тип, идите с любым и выполните проверку типа времени выполнения.

Очевидно, что правила OO наследования до сих пор применяются, поэтому, если вы хотите принять экземпляры производных классов и рассматривать их на основе базового типа, как и в

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

базовый тип является способ сделать это, не любой.Но это OO, вне сферы охвата, я просто хотел уточнить, что любой должен использоваться только тогда, когда вы не знаете, что произойдет, и для чего-нибудь еще вы должны аннотировать правильный тип.

ОБНОВЛЕНИЕ:

Typescript 2.2 добавили object типа, который указывает, что значение является непримитивный: (т.е. не number, string, boolean, symbol, undefined или null).

Рассмотрим функции, определенная как:

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

x будет иметь те же самые доступные свойства в пределах всех этих функций, но это ошибка типа для вызова d с чем непримитивным:

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

Кто-нибудь знает * почему * они решили добавить '{}', если у них уже есть 'Object'? (или наоборот, в зависимости от того, что наступило раньше). Должно быть небольшое различие, не так ли? – CletusW

+2

'{}' - это нормальный способ определения (встроенных) интерфейсов, только в этом случае вы определяете интерфейс без членов. Небольшое различие хорошо объяснено в ответе: «' {} 'extends' Object', как и все остальное в TypeScript ». – DanielM

+0

Я хочу, чтобы вы проголосовали за линию _So, в основном, когда вы не знаете тип, идите с 'any' и выполняйте проверку времени выполнения. Не используйте' any', вместо этого используйте объединение типы, которые вы проверяете: 'TypeA | InterfaceB | string'. Если у вас также есть случай по умолчанию для неизвестного типа, добавьте в объединение либо '{}', либо 'Object'. – ILMTitan

0

Добавляя к ответу Алекса и упрощая его:

Объекты более строгие с их использованием и, следовательно, дают p rogrammer больше компилирует время «оценки» мощности и, следовательно, во многих случаях обеспечивает более «возможность проверки» и предотвращает любые утечки, тогда как любой является более общим термином, и поэтому многие проверки времени компиляции могут быть проигнорированы.

0

попробовать это:

private a: Object<any> = {}; 

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

Ответы только на код не приветствуются, потому что они не объясняют, как они решают проблему. Пожалуйста, обновите свой ответ, чтобы объяснить, как это улучшается на других принятых и поддержанных ответах, которые уже заданы этим вопросом. Кроме того, этот вопрос составляет 4 года, ваши усилия будут более оценены пользователями, у которых есть последние вопросы без ответа. Пожалуйста, просмотрите [Как написать хороший ответ] (https://stackoverflow.com/help/how-to-answer). – FluffyKitten

Смежные вопросы