Typescript: Об интерфейсах

В этом уроке мы поговорим об интерфейсах. Мы узнаем, что это такое, зачем они нужны, и в каких случаях их стоит использовать вместо типов.

Что такое интерфейс

Интерфейс — это конструкция языка TypeScript, которая используется, чтобы описывать объекты и функции.

Рассмотрим следующий пример:

interface IUser {
  firstName: string;
  pointsCount: number;
}

const user: IUser = {
  firstName: 'Mark',
  pointsCount: 100,
};

В данном фрагменте мы создали интерфейс и реализовали на его основе объект user.

Интерфейс выглядит как определение объектного типа. Объектные типы и интерфейсы взаимозаменяемы почти во всех ситуациях. Сравним с примером выше:

type User = {
  firstName: string;
  pointsCount: number;
}

const user: User = {
  firstName: 'Mark',
  pointsCount: 100,
};

Здесь мы реализовали такой же объект, но уже на основе типа, а не интерфейса. Разницы почти нет.

Документация TypeScript говорит о том, что мы можем выбирать, что использовать — тип или интерфейс. Выбор зависит от ситуации. В таком случае возникает вопрос, зачем нужны интерфейсы, когда уже есть типы?

Когда использовать интерфейсы

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

Главная особенность интерфейсов связана с классами. Классы, которые реализуют интерфейсы, содержат внутри себя свойства и методы, указанные в реализуемом интерфейсе:

interface Countable {
  count(): number;
}

class SchoolClass implements Countable {
  // Тут какая-то логика
  count(): number {
    // Обязательно создать этот метод, так как он указан в интерфейсе
  }
}

const sc = new SchoolClass();
// Возвращает число студентов в классе
sc.count();

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

// А не function doSomething(obj: SchoolClass)
function doSomething(obj: Countable) {
  // Где-то внутри вызывается
  obj.count();
}

Так благодаря интерфейсам функция становится более универсальной. Мы можем передать любые объекты, соответствующие Countable, а не только SchoolClass. В программировании такая возможность называется полиморфизмом подтипов (Subtyping).

Задание

Вам дан интерфейс IVehicle. Задача состоит в том, чтобы на основе этого интерфейса реализовать класс Car, который будет иметь метод calcFuelNeeded, принимающий расстояние в километрах и возвращающий расход топлива на указанную дистанцию. Также у класса Car должна быть функция-конструктор, которая принимает и реализует свойства, указанные в интерфейсе.

const porche = new Car(4, 'red', true, 20);
console.log(porche.calcFuelNeeded(200)); // 40

Полезное

Упражнение не проходит проверку — что делать? 😶

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

  • Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет 🤨

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Мой код отличается от решения учителя 🤔

Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.

В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Прочитал урок — ничего не понятно 🙄

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.

Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются
Loading...

Ваше упражнение проверяется по этим тестам

1import Car from './index';
2
3test('Car', () => {
4  const porche = new Car(4, 'red', true, 20);
5  expect(porche.calcFuelNeeded(100)).toBe(20);
6
7  const schoolBus = new Car(30, 'yellow', true, 24);
8  expect(schoolBus.calcFuelNeeded(25)).toBe(6);
9
10  const lada = new Car(4, 'white', true, 13);
11  expect(lada.calcFuelNeeded(200)).toBe(26);
12});
13

Решение учителя откроется через:

20:00
waiting_clock