Pull to refresh
4
0
Maxim Volkov @Maxim-Wolf

User

Send message

Вы правы. TypeScript не волшебник и не дорос до зависимых типов (может ли вообще дорости имея корни в JavasScript?). Все хитрости JavaScript тянутся за ним хвостом. А стимулирует ли вас к проверке, как вы ее и написали, если вспомнить что часть элементов массива может остаться не инициализированной?

const items : string[] = [ 'foo' ];
items[4] = 'fifth';
const item = items[0]
if( typeof item === 'undefined' ) throw new Error( 'Matrix has you!' )
console.log( item.toUpperCase() )

for( let i = 0; i < items.length; i += 2 ) {
    const item = items[i]
    if( typeof item === 'undefined' ) continue;
    //без проверки - будет ошибка исполнения
    console.log( item.toUpperCase() )
}

Согласитесь, дело в том, что доступ по индексу и JavaScript может вернуть undefined на ровном месте

Эта статья не про создание кэша. Рано или поздно вы столкнетесь с необходимостью доступа к элементу массива или свойству объекта с помощью квардтатных скобок и без знания особенности типизации можете рисковать (забыть проверить наличие элемента или выход за границы). Дело в том, что без флага компилятора TypeScript неверно выводит тип результата но считает, что даже если в массиве нет ни одного элемента то результат

Ведь если компилятор решит, что item это string, но не будет вас останавливать от действия

const items:string[] = [];//пустой массив
const item = items[0]; //item: string - а это неверно.
console.log(item.toUpperCase());// Нет ошибки без фалага noUncheckedIndexedAccess
//          ^^^^ Object is possibly 'undefined'. при наличии noUncheckedIndexedAccess

При наличии флага компилятор присвоит item:string|undefined. Это уже лучше. Если вы попробуете выполнить эти же действия с полученным значением (без проверки на undefinend), компилятор сообщит об ошибке. Тем самым попросит вас уточнить тип значения

Причем флаг влияет и на доступ к элементам массива, и на доступ к элементам объекта (по индексу)

Если хук useKeydown обслуживает события клавиатуры, почему бы не донести до клиентского кода этот факт указанием типа события?

const useKeydown = (
  key: string, 
  callback: (event: KeyboardEvent) => void,
) =>{/*...*/}

Такая сигнатура может помочь при написании callback-а - TypeScript сможет вывести типы параметров "по месту".

При этом определение handler следует тоже нацелить на тип события. Пусть TypeScript проверяет соответствие ожиданий обработчика типа события указанному по имени

const handler = (event: KeyboardEvent) => {
  if (event.key === key) {
    callbackRef.current(event);
  }
}

document.addEventListener('keydown',handler);

Information

Rating
Does not participate
Registered
Activity