В этом уроке мы научимся использовать аннотации типов.
В простых случаях тип массива определяется как название типа и квадратные скобки после него, например: string[]
, number[]
. Эта схема работает и с псевдонимами типов:
type User = {
name: string
};
// При определении констант и переменных
const users: User[] = [];
// В определении функций
function foo(users: User[]) {
// ...
}
Здесь мы определяем массив, элементами которого являются объекты типа User
. В таком массиве можно хранить только объекты, которые соответствуют типу User
.
В случае составных типов, например, если мы хотим использовать объединение или описание объекта, добавляются круглые скобки — (Type)[]
:
const users: ({ name: string })[] = [];
const users: (string | null)[] = [];
const users: (User | null | { name: string })[] = [];
Внутри круглых скобок стоит описание типа, а затем уже идет квадратные скобки.
Также TypeScript дает еще один синтаксис, который описывается так: Array<Type>
. Он универсальный — с его помощью можно описать любой массив. Описывается тип в такой записи между знаками меньше и больше:
const users: Array<User> = [];
const users: Array<number> = [];
const users: Array<User> = [];
const users: Array<{ name: string }> = [];
const users: Array<string | null> = [];
Но обычно так не делают. Там, где можно использовать более короткий вариант, используют его. Форма Array
нужна в первую очередь для дженериков, которые рассмотрим позже.
Если определить пустой массив и не указать тип, то его типом автоматически станет any[]
. В такой массив можно добавить любые данные, включая вложенные массивы:
const items = [];
items.push(1);
items.push('wow');
items.push(['code-basics', 'hexlet']);
Код с any
будет работать всегда, но он выключает проверку типов. Чтобы этого не происходило, нужно всегда явно типизировать пустой массив:
const items: Array<number> = [];
Реализуйте функцию unique()
, которая убирает дубликаты из массива. Функция принимает на вход массив чисел и строк. Результатом работы функции должен быть новый массив, в котором сохраняется только первое вхождение каждого элемента. Порядок значений результата определяется порядком их появления в массиве.
unique([9, 9, 3, 8, 8]); // [9, 3, 8]
unique(['twinkle', 'twinkle', 'little', 'bat']); // ['twinkle', 'little', 'bat']
unique([1, 1, 3, 'oops!']); // [1, 3, 'oops!']
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Ваше упражнение проверяется по этим тестам
1import unique from './index';
2
3test('function', () => {
4 expect(unique([])).toEqual([]);
5 expect(unique([2, 3, -100, -100, -100])).toEqual([2, 3, -100]);
6 expect(unique(['as', 'good', 'as', 'it', 'gets'])).toEqual([
7 'as',
8 'good',
9 'it',
10 'gets',
11 ]);
12 expect(unique([1, 1, 3, 'oops!'])).toEqual([1, 3, 'oops!']);
13});
14
Решение учителя откроется через: