Друкарня від WE.UA

Лише Гуру TypeScript побачать помилку в цьому рядку коду!

Уважно подивіться на наведену нижче TypeScript функцію з одного рядку коду. В ній є проблема пов’язана з типами. Чи можете ви її побачити?

Пропоную просто зараз зупинитись та запропонувати вашу версію в коментарях.


Перша підказка

// Завантажуємо массив уявних записів із бази даних
const posts = await loadPostsFromDataBase();

// Хочемо отримати кількість доступних записів
// Але отримуємо TS2345 помилку від TypeScript
const postsCount = getArraylength(posts);

Наведений вище код призводить до помилки невідповідності типу аргументу posts до типу параметра arr. За яких умов це можливо, якщо loadPostsFromDataBase працює абсолютно коректно, а проблема саме в getArraylength?

Здогадались?


Остання підказка

В якості останньої підказки покажу тіло функції loadPostsFromDataBase:

function loadPostsFromDataBase(): readonly Post[] {
  return fetch('/api/posts')
    .then(r => r.json())
    .then(posts => Object.freeze(posts))
}

Відповідь

За замовчуванням всі типи в TS є мутабельними. Тобто, оголошуючи функцію з параметрами як тут:

function getArraylength(arr: unknown[]): number {
  return arr.length
}

Ви кажете “Ця функція потребує мутабельний масив та повертає число”.

Бачте, TypeScript майже не зважає на імплементацію вашої функції, він не бере до уваги чи справді ви змінюєте масив, чи лише читаєте його.

Тому, ви отримаєте помилку, якщо спробуєте передати аргументом readonly масив, не зважаючи на те, що насправді з точки зору JavaScript код абсолютно вірний.

const posts = await loadPostsFromDataBase(); // readonly Posts[]

const postsCount = getArraylength(posts); // ❌ The type 'readonly Post[]' is 'readonly' and cannot be assigned to the mutable type 'unknown[]'

TypeScript Playground

Рішення

Ото ж, у функції не правильно вказано тип для параметра. Як же тоді цю проблему вирішити?

Все просто. Якщо ваша функція, не змінює вхідні параметри, а це хороший патерн проєктування, тоді типи ваших параметрів повинні бути readonly:

function getArraylength(arr: readonly unknown[]): number {
  return arr.length
}

Така сигнатура каже, “Мені потрібен масив, який я буду лише читати”. І в цьому випадку, TypeScript дозволить передавати параметром як звичайні змінні, так і readonly:

const posts = []
const readOnlyPosts: readonly [] = []

getArraylength(posts) // ✅
getArraylength(readOnlyPosts) // ✅

TypeScript playground

Статті про вітчизняний бізнес та цікавих людей:

  • CRM keyCRM: зручне рішення для продажів, комунікацій і керування командою

    Успіх компанії залежить від того, наскільки швидко вона здатна опрацьовувати вхідні запити. Коли дані про клієнтів розпорошені між різними месенджерами, виникає хаос. CRM keyCRM пропонує вихід із цієї ситуації, об’єднуючи всі робочі процеси в єдиному зручному інтерфейсі.

    Теми цього довгочиту:

    Crm
  • Різниця між UX і UI, яку варто зрозуміти ще до першого заняття

    Більшість людей, які обирають професію UX чи UI, довго вважають це одним і тим самим. Насправді це два різних підходи до роботи над продуктом, і плутанина між ними гальмує розвиток ще на старті.

    Теми цього довгочиту:

    Ui-ux
  • Логіка змін: як SEO оптимізація прибирає бар’єри до зростання

    Багато компаній приходять у SEO з очікуванням швидкого ривка, але дійсний ефект починається там, де сайт перестають латати точково. Тому в центрі роботи стоїть не окрема дія, а послідовні зміни. Оптимізація сайту має прибирати системні перешкоди, а не маскувати їх новими текстами

    Теми цього довгочиту:

    Seo
  • Музичний футуризм: неймовірні інструменти XXI століття

    Еволюція музичних інструментів це один із найкрутіших проявів потужності людської уяви і потреби виразити себе через мистецтво. І хоча багато традиційних інструментів майже не змінилися за століття існування, інновації і пошук не зупиняються.

    Теми цього довгочиту:

    Музичні Інструменти
  • Стіл – всьому голова? Так, якщо його правильно підібрати

    Коли починаєш вивчати пропозицію меблевих фабрик щодо столів, дивуєшся кількості варіантів, адже вони пропонують різні розміри, різні матеріали, різноманітні форми та дизайни. Скористайтесь нашим каталогом MebelOK, щоб Ви могли підібрати найкращу модель для Вашого приміщення

    Теми цього довгочиту:

    Столи
Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Олександр Козак
Олександр Козак@kozack

16Довгочити
10KПерегляди
69Підписники
Підтримати
На Друкарні з 14 квітня 2023

Більше від автора

  • Детальний огляд семантики HTML теґів. Різниця між <section> та <article>

    Огляд семантики HTML: розрізнення між <section> та <article>, значення правильного використання тегів та їх роль у структурі вебсторінки. Дослідження важливості семантики для SEO та доступності, а також рекомендації щодо використання HTML-елементів та ролей

    Теми цього довгочиту:

    Html
  • Про доступність та UI на прикладі мого особистого сайту

    Знайомтесь це мій особистий сайт. Перший знімок те яким він був ДО другий - ПІСЛЯ сьогоднішнього патчу. І в цій короткій статті я хочу зробити маленьке ревью та розказати на прикладах ЧОМУ я реалізував деякі дивні речі.

    Теми цього довгочиту:

    Доступність
  • Як зробити нескінченну прокрутку на сайті. Або 10 недоліків та одна перевага Infinity Scroll

    В цій статті я хочу описати 10 поширених проблем, пов’язаних з нескінченною прокруткою, які розробнику доведеться вирішувати при реалізації Infinity Scroll. Та про єдину причину, чому попри всі недоліки нескінченну прокрутку активно використовують.

    Теми цього довгочиту:

    Ui-ux

Це також може зацікавити:

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

оце було цікаво, ніколи таке не траплялося, але прикольно знати на майбутнє)

Це також може зацікавити: