В TypeScript версии 2.2 был введён новый тип object. Он описывает любой непримитивный тип.
Следующие типы принято считать примитивными в JavaScript:
booleannumberstringsymbolnullundefined
Все остальные типы принято считать непримитивными.
Новый тип object представляет именно их:
// All primitive types
type Primitive =
| boolean
| number
| string
| symbol
| null
| undefined;
// All non-primitive types
type NonPrimitive = object;Давайте посмотрим, как object поможет нам более точно описывать типы.
Описания типов, использующие тип object
С релизом TypeScript версии 2.2 описания типов стандартной библиотеки были обновлены с использованием нового типа object. Например, методы Object.create() и Object.setPrototypeOf() теперь описывают параметр прототипа, как object | null:
interface ObjectConstructor {
/**
* Creates an object that has the specified prototype or that has null prototype.
* @param o Object to use as a prototype. May be null.
*/
create(o: object | null): any;
/**
* Sets the prototype of a specified object o to object proto or null. Returns the object o.
* @param o The object to change its prototype.
* @param proto The value of the new prototype or null.
*/
setPrototypeOf(o: any, proto: object | null): any;
// ...
}Если передать примитивный тип, в качестве прототипа в Object.setPrototypeOf() или в Object.create(), то, во время исполнения кода, будет выброшено исключение TypeError. Теперь TypeScript отлавливает такие ошибки на этапе компиляции:
const proto = {};
Object.create(proto); // OK
Object.create(null); // OK
Object.create(undefined); // Error
Object.create(1337); // Error
Object.create(true); // Error
Object.create("oops"); // ErrorДругим местом для применения типа object является структура данных WeakMap. Ключи которой должны быть объектами и не могут являться примитивами. Это требование нашло отражение в тайпингах:
interface WeakMap<K extends object, V> {
delete(key: K): boolean;
get(key: K): V | undefined;
has(key: K): boolean;
set(key: K, value: V): this;
}object vs Object vs {}
Возможно Вас смутит, что TypeScript определяет несколько типов, имеющих похожие имена, но представляющие разные концепции:
- object
- Object
- {}
Мы рассмотрели новый тип object выше. Теперь давайте обсудим, что же из себя представляют Object и {}.
Тип Object
Typescript определяет другой тип, с почти таким же названием, как и новый тип object, и это тип Object. В то время как object (с маленькой буквы) представляет все непримитивные типы, Object (с большой буквы) описывает функциональность, общую для все JavaScript объектов. Например, методы toString() и hasOwnProperty(). В файле lib.es6.d.ts тип Object определяется следующим образом:
interface Object {
// ...
/** Returns a string representation of an object. */
toString(): string;
/** Returns a date converted to a string using the current locale. */
toLocaleString(): string;
/** Returns the primitive value of the specified object. */
valueOf(): Object;
/**
* Determines whether an object has a property with the specified name.
* @param v A property name.
*/
hasOwnProperty(v: string): boolean;
/**
* Determines whether an object exists in another object's prototype chain.
* @param v Another object whose prototype chain is to be checked.
*/
isPrototypeOf(v: Object): boolean;
/**
* Determines whether a specified property is enumerable.
* @param v A property name.
*/
propertyIsEnumerable(v: string): boolean;
}Тип {}
Есть ещё один тип, который очень похож: {}, пустой тип объекта. Он описывает объект у которого нет собственных свойств. При попытке доступа к произвольным свойствам такого объекта TypeScript выдаёт ошибку во время компиляции:
// Type {}
const obj = {};
// Error: Property 'prop' does not exist on type '{}'.
obj.prop = "value";Тем не менее, вы можете использовать все свойства и методы, описанные в типе Object, которые неявно доступны через цепочку прототипов:
// Type {}
const obj = {};
// "[object Object]"
obj.toString();Комментарии (18)

DarkByte2015
16.01.2018 17:21Вообще это нормально, но они зря его назвали также как существующий Object. Будет большая путаница несмотря на все объяснения. Разница в регистре одной буквы это не о чем. Вообще это очень напоминает C#. Там есть классы (class) и структуры (struct). Под структурой понимается любой ValueType (числа, булевые значения, в общем примитивные типы), а под классами как раз — классы (то что тут назвали object). Также есть корень иерархии — тип System.Object (можно с маленькой буквы object — алиас просто). Короче я о том что надо было поднапрячься и все же придумать имя получше…

tenbits
17.01.2018 03:07На самом деле, такое наименование следует тому же принципи что и
Number:number,String:string,Boolean:boolean. С этим же ни у кого проблем не возникает.
DarkByte2015
17.01.2018 09:19Тогда это скорее как в Java. Там тоже есть примитивный int, а есть объект Integer.
mayorovp
17.01.2018 09:57Именно так и есть. Точно так как и в Java,
Number— это упакованная версияnumber.
Разве что вот теперь
Objectиobjectотличаются не упакованностью, а занимают разные места в иерархии наследования...

FlamyXD
16.01.2018 17:22Разве null и undefined являются типами? А не значениями?

SayLovePlz Автор
16.01.2018 17:22
FlamyXD
16.01.2018 17:34Там написано, что это «Специальное значение».

DarkByte2015
16.01.2018 17:52+1Значение null не относится ни к одному из типов выше, а образует свой отдельный тип, состоящий из единственного значения null

FlamyXD
16.01.2018 19:58-1Это просто специальное значение, которое имеет смысл «ничего» или «значение неизвестно».

Vadem
17.01.2018 17:12+1Строго говоря, стандарт определяет именно отдельные типы для null и undefined:
ECMAScript Language Types
И у них ровно по одному значению.
vanxant
Мммм, я правильно понимаю, что построили сначала строго-типизированную надстройку над мерзко-утино-почтине-типизированным javascript, а потом, через N лет, это всё решили отменить?)
Shtucer
Нет. Это было сделано раньше. Тип
anyбыл с самого сразу. Иначе, как бы оно дружило с JS?vanxant
Нет, ну
anyэтоany. Заглушка в стиле «возвращает то, не знаю что». Аobjectэто именно объект, просто с утиной типизацией (т.е. требования к наличию определённых свойств в этом объекте определяются нижележащим кодом).Shtucer
Ну, как бы
any, как мне кажется, делает "строго-типизированную надстройку" не такой уж и строгой прям с фундамента. Заглушкаanyне только про "возвращает то, не знаю что". Ее можно пихать во все места и не заморачивать мозг всеми этими типизациями. Сobjectуже не то манто. Как, повторюсь, мне кажется.eliduvid
На сколько я понял из статьи это тоже заглушка типа any, которая только проверяет на не примитвность. Это не значит, что можно обращаться к любым свойствам без приведения.
PYXRU
Благодаря этой заглушки они усилили типизацию как раз, потому что теперь если метод принципе не может принять примитив он не будет допущен ts компилятором. any — такое бы позволил.
alex6636
Что не отменяется мерзости js
mayorovp
Нет, они ввели новый тип для того чтобы более точно описать некоторые существующие интерфейсы. Например, тот же
Object.create. Каким образом уточнение модели ее вдруг отменяет?