#reactjs #typescript #recoiljs
#reactjs #машинописный текст #recoiljs
Вопрос:
Итак, я думаю, что у моего линтера typescrpt короткое замыкание, потому что я ни за что на свете не могу понять, почему продолжает возникать эта ошибка линтинга.
Type 'IConnectionState' is not assignable to type '{ connected: false; type: "none"; }'
Ниже приведен мой код, который, как вы можете ясно видеть, не должен иметь никаких последствий.
export interface IConnectionState {
connected: boolean;
type: 'none' | 'player' | 'host';
}
export const ConnectionState: RecoilState<IConnectionState> = atom({
key: 'connectionState',
default: {
connected: false,
type: 'none'
}
});
Если это поможет, я использую отдачу. Но, глядя на типы отдачи, RecoilState
should type принимает подтип default
значения, присвоенного его объекту options .
Я так растерялась.
Ответ №1:
Я вижу аналогичную проблему с более простым интерфейсом.
export const myState: RecoilState<boolean> = atom({
key: 'myState',
default: false,
});
// Type '<RecoilState<false>' is not assignable to type 'RecoilState<boolean>'.
Я могу это исправить, либо объявив default: false as boolean
, либо, что, вероятно, лучше, добавив generic <T>
в вызов метода:
export const myState: RecoilState<boolean> = atom<boolean>({
key: 'myState',
default: false,
});
Или вы можете полностью исключить объявления типов, и TypeScript вычислит это.
Ответ №2:
На самом деле линтер работает так, как ожидалось. Вы устанавливаете тип ConnectionState
to be IConnectionState
, но вы никогда не включаете свойство key
в интерфейс.
Интерфейс IConnectionState
правильный, но он должен быть вложен в другой интерфейс.
const NONE = 'none';
const PLAYER = 'player';
const HOST = 'host';
const CONNECTIONSTATE = "connectionState";
type TType = typeof NONE | typeof PLAYER | typeof HOST;
interface IConnectionStateDefault {
connected: boolean;
type: TType
}
interface IConnectionState {
key: typeof CONNECTIONSTATE,
default: IConnectionStateDefault
}
export const ConnectionState: RecoilState<IConnectionState> = atom({
key: "connectionState",
default: {
connected: false,
type: 'none'
}
});
Если IConnectionState
у него больше key
значений, просто сделайте то же самое, что и я, с TType
тем, где вы формируете объединение по возможным типам, которые key
могут существовать как.
Ответ №3:
Это то, что я делал в нашем monorepo.
Создайте глобальный файл для ВСЕХ ключей, чтобы попытаться сохранить понимание того, что вы не хотите никаких столкновений, поскольку существует один реестр Recoil.
export enum GlobalRecoilKeyEnum {
ATOM_SOME_BOOLEAN_KEY= "ATOM_SOME_BOOLEAN_KEY",
}
Создайте региональный файл атомов (Nx позволяет мне изолировать доступ с помощью linting.)
export const SomeBooleanAtom = atom({
key: GlobalRecoilKeyEnum.ATOM_SOME_BOOLEAN_KEY,
default: false
});
Способы доступа к функциональным компонентам.
const isSomeBoolean: boolean = useRecoilValue<boolean>(SomeBooleanAtom);
const setSomeBoolean: SetterOrUpdater<boolean> = useSetRecoilState<boolean>(SomeBooleanAtom);
const [isPractice, setSomeBoolean]: [boolean, SetterOrUpdater<boolean>] = useRecoilValue<boolean>(SomeBooleanAtom);