Описать правильно функцию
Имеется такой код:
import { createContext, useState } from 'react';
interface IUser
{
name: string;
}
interface IValue
{
user: IUser;
isAuth: boolean;
}
export interface IUserContext
{
}
export const UserCtx = createContext<IUserContext>({} as IUserContext);
function App()
{
const [ user, setUser ] = useState<IUser>({} as IUser);
const [ isAuth, setIsAuth ] = useState<boolean>(false);
const setValue: <T extends keyof IValue>(key: T, value: IValue[ T ]) => void = (key, value) =>
{
localStorage.setItem(key, JSON.stringify(value));
switch (key)
{
case "user": {
setUser(value);
break;
}
case "isAuth": {
setIsAuth(value);
break;
}
}
};
setValue("user", { name: "test" });
const userContext: IUserContext =
{
user,
isAuth,
setValue
};
}
Как мне правильно описать функцию setValue? На данный момент я получаю ошибки:
(parameter) value: boolean | IUser Аргумент типа "boolean | IUser" нельзя назначить параметру типа "SetStateAction". Тип "IUser" не может быть назначен для типа "SetStateAction". ts(2345)
Ответы (1 шт):
Автор решения: xydope
→ Ссылка
Так это работать не будет. То, что вы хотите, лучше делать через хук useReducer
Тем не менее, некоторые рабочие практики из типизации редюсеров можно применить к вашему варианту (к слову, это тоже плохая практика)
Удалил ненужный для примера код.
interface IUser {
name: string;
}
//ключи сеттеров
enum keys {
isAuth = "isAuth",
user = "user"
}
//креатор объекта аутентификации
const createAuthValue = (authState: boolean) =>
({
key: keys.isAuth,
auth: authState,
} as const);
//креатор объекта с юзером
const createUserValue = (user: IUser) =>
({
key: keys.user,
user: user,
} as const);
//возможные значения, которые принимает setValue
type Value = ReturnType<typeof createAuthValue> | ReturnType<typeof createUserValue>
function App() {
const [user, setUser] = useState<IUser>({} as IUser);
const [isAuth, setIsAuth] = useState<boolean>(false);
const setValue= (value: Value) => {
switch (value.key) {
case keys.user: {
setUser(value.user);
break;
}
case keys.isAuth: {
setIsAuth(value.auth);
break;
}
}
};
//вызываем общий сеттер и передаем туда креатор объекта с юзером
setValue(createUserValue({ name: "test" }));
}
В ответе на этот вопросе есть ссылки для более подробный инфы по типизации редюсера.
