Devs Hive
Повернутися до всіх запитань

Що таке Type Narrowing в TypeScript?

MiddleSeniorTypeScript
Зустрічали на інтервʼю:1 користувач

Це дуже поширене запитання в контексті розмови про TypeScript. Якщо ви почули його на інтервʼю, це може бути хорошим сигналом того, що TS в проєкті використовується не просто для галочки.

Type Narrowing(звуження) означає конкретизацію типу для TypeScript. Наприклад, в нас є змінна з типом string | number i narrowing в цьому випадку буде означати перевірку змінної на те чи її значення має string чи number. В залежності від реального значення, ми будемо мати різну імплементацію, для різних типів даних.

Існує декілька способів звузити тип. В контексті цього запитання ми розберемо тільки базові, які зазвичай запитують на інтервʼю:

typeof

Це найпростіший спосіб, який використовується для примітивів. Якщо TypeScript зустрічається з Union типом, він не дозволяє викликати методи чи доступатись до полів, які присутні тільки в одному з типів. В такому випадку, вам потрібно явно перевірити, що значення є конкретним типом. Або використати as, але це вважається Bad Practice в TypeScript 👹

function format(value: string | number): string {
/**
* toUpperCase доступний тільки в string тому TS видасть помилку,
* якщо ми захочемо викликати його. Щоб викликати метод, TS має впевнитись
* що тип дійсно string, для цього ми використовуємо typeof. Це і є звуження типів
* */
if (typeof value === "string") {
return value.toUpperCase();
}
// Якщо тип не string, значить він number i для value доступні всі поля і методи
return value.toFixed(2);
}

instanceof

Це звуження типу, через перевірку чи є об’єкт екземпляром певного класу. Він використовується не так часто, як наприклад typeof, але для розуміння Type Narrowing потрібно розібрати і його. Типовий приклад використання, це керування помилками:

class NotFoundError extends Error {
constructor(public resource: string) {
super("Not found");
}
}

const handleError = (e: unknown) => {
// В цьому випадку Type Narrowing допомагає нам по різному опрацьовувати
// HTTP помилки, які є класами. Також, unknown забовʼязує нас зробити type narrowing
// перед використанням полів чи методів
if (e instanceof NotFoundError) {
console.log(`Missing: ${e.resource}`);
}

if (e instanceof Error) {
console.log(e.message);
return;
}

console.log("Unknown error");
}

Зазвичай, розуміння typeof i instanceof цілком достатньо в контексті інтервʼю. Але якщо ви хочете копнути трохи глибше, ось інші способи Type Narrowing:

  1. Discriminated unions
  2. Operator in
  3. Type guards
  4. Assertion functions

Зустрічав на інтервʼю?

Коментарі (0)

Увійдіть, щоб залишити коментар

Поки що немає коментарів. Будьте першим!