Что может быть неправильно в решении функции для вычисления площади фигур с использованием типов и интерфейсов TypeScript
Что проверяют
Задачу дают не ради формулы площади. Смотрят, умеете ли вы описать данные так, чтобы невозможное состояние не компилировалось, знаете ли про сужение типов и помните ли, что типы существуют только до сборки.
Как отвечать
Разбирайте типовое решение по слабым местам. Обычно кандидат пишет один интерфейс со всеми полями сразу:
interface Shape {
kind: string;
radius?: number;
side?: number;
}Здесь сломано три вещи. Поля необязательные, поэтому у круга может не быть радиуса, и в коде появляется shape.radius!, который просто выключает проверку. Поле kind объявлено как string, значит опечатка в сравнении не ловится. И ничто не мешает создать объект с радиусом и стороной одновременно.
Правильнее размеченное объединение и switch по общему полю:
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(shape: Shape): number {
switch (shape.kind) {
case "circle": return Math.PI * shape.radius ** 2;
case "square": return shape.side ** 2;
default: {
const rest: never = shape;
return rest;
}
}
}Ветка с never даёт проверку полноты: добавили в тип треугольник и забыли case, сборка падает. Явный тип результата number не даёт функции тихо вернуть undefined.
Отдельно скажите про границу: данные с сервера типами не проверяются, там нужен разбор в рантайме.
Где спотыкаются
Считают, что интерфейс сам по себе решает задачу. Интерфейс с необязательными полями плюс приведение через as и восклицательный знак дают зелёную сборку и падение на реальных данных, потому что все проверки кандидат отключил вручную.
Пробуют различать фигуры через instanceof по интерфейсу. Интерфейсы и псевдонимы типов стираются при компиляции, в рантайме их нет. Различать можно по полю, по оператору in или собственными функциями-предикатами, а классы подходят, только если объекты действительно создаются через new.
Не делают проверку полноты и получают молчаливую ошибку при расширении. Если тип результата не указан, а в конце стоит return 0, новая фигура вернёт ноль, и тесты на старых фигурах этого не покажут.