Вопрос или проблема
Я получаю следующую ошибку:
Тип ‘string | number | boolean’ не может быть присвоен типу ‘never’.
при присвоении внутри функции mutateData. Я не совсем понимаю, почему, потому что данные инициализируются как пустой массив с правильным типом.
type FileObject = {
name: string
path: string
returnStatus: number
dataPrepared: boolean
}
type Keys = keyof FileObject
type KeyValue = {
[key in Keys]: {key: key, value: FileObject[key]}
}[Keys]
type Mutation = {
index: number
} & KeyValue
const data: FileObject[] = []
function mutateData(input: Mutation) {
data[input.index][input.key] = input.value
}
Я считаю, что вышеуказанное решение должно работать, поскольку тип Mutation состоит из индекса и правильных объединенных типов пар ключ/значение.
Ответ или решение
Ошибка, с которой вы столкнулись, возникает из-за того, что TypeScript не может правильно сопоставить типы при выполнении операции присваивания в вашем коде. Давайте разберём вашу проблему шаг за шагом и предложим решение.
Причина ошибки
Тип KeyValue
, который вы используете в типе Mutation
, не определяет key
и value
как соответствующие типы, которые могут быть использованы для доступа к объекту FileObject
. Из-за этого TypeScript считает, что присвоение значения к data[input.index][input.key]
не подходит с точки зрения типов, и выдаёт ошибку, сообщая, что тип string | number | boolean
не совпадает с типом never
.
Решение проблемы
Чтобы исправить данное поведение, вы можете использовать перегрузку типов для функции mutateData
. Это позволит вам явно указать типы для ключа и значения, что упростит управление типами. Таким образом, мы сможем сделать следующее:
- Убедиться, что
input.key
корректно понимается как один из ключейFileObject
. - Избежать конфликта типов при присвоении значений.
Вот исправленный код:
type FileObject = {
name: string;
path: string;
returnStatus: number;
dataPrepared: boolean;
}
type Keys = keyof FileObject;
type KeyValue<K extends Keys> = {
key: K;
value: FileObject[K];
}
type Mutation<K extends Keys> = {
index: number;
} & KeyValue<K>;
const data: FileObject[] = [];
// Функция принимает в качестве параметра объект Mutation с типом K
function mutateData<K extends Keys>(input: Mutation<K>) {
data[input.index][input.key] = input.value;
}
// Пример использования
data.push({
name: "example.txt",
path: "/path/to/example.txt",
returnStatus: 200,
dataPrepared: true
});
// Теперь функция может присваивать значения корректно
mutateData({ index: 0, key: "name", value: "newname.txt" });
mutateData({ index: 0, key: "returnStatus", value: 404 });
Комментарии к исправлениям
-
Перегрузка типов: Мы добавили обобщение
<K extends Keys>
кMutation
иmutateData
, что позволяет TypeScript выяснить, какие конкретные ключи и соответствующие значения используются при присвоении. -
Пример использования: В конце кода вы можете видеть пример добавления объекта в массив
data
и вызовmutateData
, который корректно обновляет значения.
Таким образом, это должно устранить вашу проблему с ошибкой типов и обеспечить корректность работы программы. Если у вас есть дополнительные вопросы, не стесняйтесь спрашивать.