Кроме простых типов данных, как и в javascript, можно создавать сложные комплексные объекты, которые состоят из других объектов и примитивных данных. Например:
let person = {name:"Tom", age:23}; console.log(person.name); // альтернативный вариант получения свойства console.log(person["name"]);
Но несмотря на то, что это фактически тот же самый объект, что мы могли бы использовать в JavaScript, в силу строготипизированности TS мы имеем в данном случае ограничения. В частности, если у нас будет следующий код:
let person = { name: "Tom", age: 23 }; person = { name: "Bob" }; // ! Ошибка
То на второй строке мы получим ошибку, поскольку компилятор после первой строки предполагает, что объект person будет иметь два свойства
name и age, которые имеют тип string и number соответственно. То есть в данном случае переменная person
представляет тип { name: string; age: number }
.
И мы могли написать так:
let person: { name: string; age: number } = { name: "Tom", age: 23 }; console.log(person.name);
Поэтому данной переменной мы можем присвоить другой объект, который соответствует типу { name: string; age: number }
по названиям, количеству и типу свойств, как в следующем случае
let person = { name: "Tom", age: 23 }; person = { name: "Bob", age: 35 }; // Норм
TypeScript позволяет сделать свойства необязательными. Для этого после названия свойства указывается знак вопроса ?
let person: { name: string; age?: number }; // Свойство age - необязательное
В данном случае свойство age
является необязательным, поэтому мы можем не предоставлять для него значение:
let person: { name: string; age?: number }; // Свойство age - необязательное person = { name: "Tom", age: 23 }; console.log(person.name); // Tom person = { name: "Bob"}; // Норм, свойство age - необязательное console.log(person.name); // Bob
При обращении к неустановленному свойству мы получим undefined:
let person: { name: string; age?: number } = { name: "Tom", age: 23 }; console.log(person.age); // 23 person = { name: "Bob"}; console.log(person.age); // undefined
Поэтому при операциях с таким свойством мы можем проверять его на значение undefined
:
let person: { name: string; age?: number } = { name: "Tom", age: 36}; if (person.age !== undefined) { console.log(person.age); }
Функция может принимать объекты в качестве параметров и могут возвращать объект. В этих случаях необходимо указать тип объекта для параметров и результата функции. Например, объект как параметр функции:
function printUser(user: { name: string; age: number}) { console.log(`name: ${user.name} age: ${user.age}`); } let tom = {age: 36, name: "Tom"}; printUser(tom);
В данном случае параметр функции printUser представляет тип { name: string; age: number}
-
то есть объект, который имеет два свойства типов string и number.
При этом объект, передаваемый в качестве параметра, может быть более широким - содержать больше свойств, но главное, чтобы он содержал те свойства, которые предусмотрены для параметра функции:
function printUser(user: { name: string; age: number}) { console.log(`name: ${user.name} age: ${user.age}`); } let bob = {name: "Bob", age: 44, isMarried: true}; printUser(bob);
Здесь переменная bob
представляет тип {name: string, age: number, isMarried: boolean}
, тем не менее он также соответствует
определению типа { name: string; age: number}
.
Объект как результат функции:
function defaultUser(): { name: string; age: number} { return {name: "Tom", age: 37}; } let user = defaultUser(); console.log(`name: ${user.name} age: ${user.age}`);
Оператор in позволяет проверить наличие определенного свойства в объекта. Он возвращает true
, если свойство есть в объекте,
и false
, если свойство отсутствует. Например:
let tom: { name: string; age?: number } = { name: "Tom", age: 23 }; let bob: { name: string; age?: number } = { name: "Bob"}; function printUser(user: { name: string; age?: number }){ if("age" in user){ console.log(`Name: ${user.name} Age: ${user.age}`); } else{ console.log(`Name: ${user.name}`); } } printUser(tom); printUser(bob);
Здесь функция printUser()
принимает объект типа { name: string; age?: number }
, то есть свойство age
в таком объкте может присутствовать, а может
отсутствовать. Поэтому применяем оператор in
для проверки наличия свойства:
if("age" in user){
Название свойства передается как строка.
Если функция принимает объект в качестве параметра, то TypeScript позволяет автоматически разложить его на свойства:
function printUser({name, age}: { name: string; age: number}) { console.log(`name: ${name} age: ${age}`); } let tom = {name: "Tom", age: 36}; printUser(tom);
Здесь функция printUser()
в качестве параметра принимает объект из двух свойств. Запись {name, age}
указывает, что свойства объекта автоматически
будут разложены на два параметра: name и age. Главное, чтобы названия этих параметров соответствовали названиям свойств объекта.
Некоторые параметры могут необязательными:
function printUser({name, age}: { name: string; age?: number}) { if(age!==undefined){ console.log(`name: ${name} age: ${age}`);} else {console.log(`name: ${name}`);} } let tom = {name: "Tom"}; printUser(tom); // name: Tom let bob = {name: "Bob", age: 44}; printUser(bob); // name: Bob age: 44
В данном случае параметр age
является необязательным. Кроме того, имеет значение по умолчанию. Поэтому функция может принимать объект без свойства age.
Также они могут принимать значения по умолчанию:
function printUser({name, age = 25}: { name: string; age?: number}) { console.log(`name: ${name} age: ${age}`); } let tom = {name: "Tom"}; printUser(tom); // name: Tom age: 25 let bob = {name: "Bob", age: 44}; printUser(bob); // name: Bob age: 44