Interface и Type в Typescript
Для описания структуры объекта можно использовать interface или type.
Интерфейс
Interface — абстракция, которая описывает структуру объекта.
Существует объект audi.
const audi = {
foundationDate: 1909,
Location: "Germany",
site: "audi.ru",
speed: () => {
return "Формулы скорости, расстояния и времени: V = S / T";
}
};
Для типизация объекта можно написать audi: object или добавить анонимный объект.
Объект.
const audi: object = {
foundationDate: 1909,
Location: "Germany",
site: "audi.ru",
speed: () => {
return "Формулы скорости, расстояния и времени: V = S / T";
}
}
console.log(audi.Location);
//Germany
Анонимный объект.
При анонимном объекте необходимо типизировать поля объекта.
const audi: {
foundationDate: number;
Location: string;
site: string;
speed: () => string;
} = {
foundationDate: 1909,
Location: "Germany",
site: "audi.ru",
speed: () => {
return "Формулы скорости, расстояния и времени: V = S / T";
}
}
console.log(audi.Location);
//Germany
Interface.
Если нам потребуется ещё один объект с точно таким же типом, придётся писать идентичный анонимный тип. Чтобы избежать дублирования кода, создадим интерфейс, в котором опишем типы полей нашего объекта.
Обычно названия интерфейсов указывают с I. Это негласное правило, придерживаться которого необязательно. Но мы рекомендуем ему следовать, ведь тогда из названия сразу понятно, что перед нами интерфейс. А это помогает не запутаться в случае, когда мы объявляем и применяем тип в разных файлах.
interface ICar {
foundationDate: number;
Location: string;
site: string;
speed: () => string;
}
const audi: ICar = {
foundationDate: 1909,
Location: "Germany",
site: "audi.ru",
speed: () => {
return "Формулы скорости, расстояния и времени: V = S / T";
}
};
const lada: ICar = {
foundationDate: 1966,
Location: "Russia",
site: "lada.ru",
speed: () => {
return "Формулы скорости, расстояния и времени: V = S / T";
}
};
console.log(audi.Location);
console.log(lada.Location);
Всё, что мы описали в интерфейсе, обязательно должно содержаться в объекте. Теперь у всех полей строго определены типы. И полю с типом string мы можем присвоить только строковое значение.
Readonly.
Поля помеченные readonly, не переопределяются. Так что при попытке добавить новую пару ключ-значение получим ошибку: Cannot assign to ‘Location’ because it is a read-only property.ts(2540).
interface ICar {
readonly foundationDate: number;
readonly Location: string;
site: string;
speed: () => string;
}
const audi: ICar = {
foundationDate: 1909,
Location: "Germany",
site: "audi.ru",
speed: () => {
return "Формулы скорости, расстояния и времени: V = S / T";
}
};
const lada: ICar = {
foundationDate: 1966,
Location: "Russia",
site: "lada.ru",
speed: () => {
return "Формулы скорости, расстояния и времени: V = S / T";
}
};
console.log(audi.Location = "China");
//Cannot assign to 'Location' because it is a read-only property.ts(2540)
Необязательное поле следует помечать знаком ?.
interface ICar {
readonly foundationDate: number;
readonly Location: string;
site: string;
speed: () => string;
sportCars?: string;
}
const audi: ICar = {
foundationDate: 1909,
Location: "Germany",
site: "audi.ru",
speed: () => {
return "Формулы скорости, расстояния и времени: V = S / T";
},
sportCars: "Audi R8 V10"
};
const lada: ICar = {
foundationDate: 1966,
Location: "Russia",
site: "lada.ru",
speed: () => {
return "Формулы скорости, расстояния и времени: V = S / T";
}
};
console.log((audi.sportCars));
console.log(lada.Location);
//Audi R8 V10
//Russia
Extends.
Интерфейсы могут расширять друг друга.
interface IGermanyCars {
name: string;
speed: number;
}
const mersedes: IGermanyCars = {
name: "mersedes",
speed: 300,
}
interface IGermanySportCars extends IGermanyCars {
nameSportCar: string
}
const GermanySportCars: IGermanySportCars = {
name: "mersedes",
nameSportCar: "Audi R8 V10",
speed: 400,
}
console.log(mersedes.name);
console.log(GermanySportCars.nameSportCar);
//mersedes
//Audi R8 V10
Тип
type TCar = {
readonly foundationDate: number;
readonly Location: string;
site: string;
speed: () => string;
sportCars?: string;
}
const audi: TCar = {
foundationDate: 1909,
Location: "Germany",
site: "audi.ru",
speed: () => {
return "Формулы скорости, расстояния и времени: V = S / T";
},
sportCars: "Audi R8 V10"
};
console.log(audi.Location);
//Germany
Отличия Type от Interface.
| Interface | Type |
|---|---|
interface ICars {model: string;} | type TCars = {}; |
| ключевое слово interface | ключевое слово type |
| interface ICar { // нет знака = | type TCar = { // есть знак = |
| } // нет ; | }; // есть ; |
| Интерфейсы расширяются. | Типы не расширяются. |
Типы в отличие от интерфейсов не расширяются.
interface ICar {
model: string
}
interface IModel extends ICar {
speed: number
}
const audi: IModel = {
model: "Audi",
speed: 310
}
Расширение типов и интерфейсов
Расширение типов.
type TCar = {
model: string
};
type TModel = TCar & {
speed: number
};
const audi: TModel = {
model: "Audi",
speed: 310
}
console.log(audi.model);
//Audi
Расширение интерфейсов.
interface ICar {
model: string
}
interface IModel {
speed: number
}
const audi: ICar & IModel = {
model: "Audi",
speed: 310
}
console.log(audi.model);
//Audi
Добавление полей в существующий тип
В псевдоним типа нельзя добавлять новое поле, тогда как в интерфейсе это обычное дело.
interface ICar {
model: string;
}
interface IModel {
speed: number;
}
interface IModel {
racing: number
}
const audi: ICar & IModel = {
model: "Audi",
speed: 310,
racing: 4
};
console.log(audi.racing);
//4
Реализация интерфейса классом
В ООП классы могут реализовывать интерфейсы. Описываем в интерфейсах поля и методы, которые должен содержать класс. Реализовать псевдоним типа классом — нельзя. implements необходимо указывать при создании классов от какого интерфейса он реализуется.
interface ICar {
model: string;
}
interface IModel extends ICar{
readonly speed: number;
}
interface IModel {
readonly racing: number;
speedTest: () => string;
}
class carTest implements IModel {
public readonly model: string;
public readonly speed: number;
public racing: number;
constructor (model: string, speed: number, racing: number) {
this.model = model;
this.speed = speed;
this.racing = racing;
}
public speedTest () {
console.log("врум врум");
return "Дракрейсинг"
}
}
const AUDI = new carTest("AUDI R 8", 300, 4)
AUDI.speedTest();
//врум врум
Примеры
type TFullName = {
readonly name: string;
readonly sername: string;
age: number
};
type TPerson = {
position: string;
readonly fullname: TFullName;
};
const Microsoft: readonly TPerson[] = [
{
position: "co-founder",
fullname: {name: "Bill", sername: "Gates", age: 67},
},
{
position: "co-founder",
fullname: {name: "Paul", sername: "Alien", age: 65},
}
]
console.log(Microsoft[0].fullname);
//{name: "Yura", sername: "Gates", age: 34}
console.log(Microsoft[1].fullname);
//{name: "Paul", sername: "Alien", age: 65}
console.log(Microsoft[0].fullname.name = "Yura");
//Cannot assign to 'name' because it is a read-only property.ts(2540)
console.log(Microsoft[0].fullname.age = 34);
//34
interface IStype {
[key: string]: string
}
const borderStyle: IStype = {
color: "black",
border: "1px solid red",
borderRaduis: "10px",
}
console.log(borderStyle.color);
//black
Filed under: TypeScript - @ 07.01.2023 13:59