Извините за заголовок, действительно не знаю, какое имя подойдет для этого вопроса.
Я хочу создать функцию setItem, которая установит значение ключа в объекте:
const setItem = <T, U extends keyof T>(obj: T) => (key: U, value): void => {
obj[key] = value
}
const person = {
name: 'James',
age: 13,
}
const setPerson = setItem(person)
setPerson('name', 125)
Никаких ошибок времени компиляции, даже если мы установили свойство имени в число. (потому что сейчас значение typeof any).
Итак, как я могу сказать TS, что obj[key] является значением typeof?






Включите режим компилятора --strict, чтобы value выдал вам «неявное any» предупреждение. Тип value должен быть T[U], тип поиска.
Обратите внимание: если вы хотите, чтобы каррированная универсальная функция работала правильно, вам нужно поместить параметры типа в нужное место:
const setItem = <T>(obj: T) => <U extends keyof T>(key: U, value: T[U]): void => {
obj[key] = value;
}
Вы хотите, чтобы setItem(obj) возвращал общую функцию, которая может принимать любые U extends keyof T вместо key, поэтому параметр U должен быть в этой возвращаемой функции. Если поставить <T, U> на первую функцию, то компилятор попытается вывести U из значений, переданных в setIem(), и не сможет. В конечном итоге он расширится от U до keyof T, и это не сможет предотвратить ошибки.
Давайте удостоверимся, что версия здесь работает:
const person = {
name: 'James',
age: 13,
}
const setPerson = setItem(person)
setPerson('name', 10); // error
setPerson('name', 'Jill'); // okay
setPerson('age', 10); // okay
setPerson('age', 'Jill'); // error
Ссылка на код для игровой площадки
Надеюсь, это поможет; удачи!
Вы говорите, что у вас все еще есть ошибка? Или все в порядке?
Я имею в виду, хорошо, что у меня ошибка с неправильным типом :D. Итак, ваше решение решило мою проблему. :)
Классная штука, спасибо! Сначала я получил ok со значением: T[U], но после того, как я поставил декларацию U справа, компилятор выдал ошибку!