Друкарня від 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

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

  • Вітаємо з Різдвом Христовим!

    Друкарня та платформа WE.UA вітають всіх наших читачів та авторів зі світлим святом Різдва! Зичимо всім українцям довгожданого миру, міцного здоровʼя, злагоди, родинного затишку та втілення всього доброго і прекрасного, чого вам побажали колядники!

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

    Різдво
  • Каблучки – прикраси, які варто купувати

    Ювелірні вироби – це не тільки спосіб витратити гроші, але і зробити вигідні інвестиції. Бо вартість ювелірних виробів з кожним роком тільки зростає. Тому купуючи стильні прикраси, ви вигідно вкладаєте кошти.

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

    Як Вибрати Каблучку
  • П'ять помилок у виборі домашнього текстилю, які псують комфорт сну

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

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

    Домашній Текстиль
  • Як знайти житло в Києві

    Переїжджаєте до Києва і шукаєте житло? Дізнайтеся, як орендувати чи купити квартиру, перевірити власника та знайти варіанти, про які зазвичай не говорять.

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

    Агентство Нерухомості
  • Як заохотити дитину до читання?

    Як залучити до читання сучасну молодь - поради та факти. Користь читання для дітей - основні переваги. Розвиток дітей - це наше майбутнє.

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

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

9.7KПрочитань
1Автори
68Читачі
Підтримати
На Друкарні з 14 квітня

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

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

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

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

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

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

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

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

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

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

    Ui-ux

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

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

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

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