[英]How can I avoid optional chaining in Typescript?
I'm trying to store object data called Targetfarms
in redux. I assigned a type called Farmstype
to Targetfarms
.我试图在 redux 中存储名为
Targetfarms
的 object 数据。我为Targetfarms
分配了一个名为Farmstype
的类型。
However, when I bring Targetfarms
with useSelector
in the MainPage
component and I want to use targetfarm.aircon
, if I do not use optional chaining in Targetfarms
, this error occurs.但是,当我在
MainPage
组件中使用带有Targetfarms
的useSelector
并且我想使用targetfarm.aircon
时,如果我不在Targetfarms
中使用可选链接,则会发生此错误。
Targetfarms is possibly null,
If I use optional chaining, I can get Targetfarms
data normally, but I don't want to use optional chaining as much as possible.如果我使用optional chaining,我可以正常获取
Targetfarms
数据,但我不想尽可能使用optional chaining。
How can I fix my code?我该如何修复我的代码?
This is my code:这是我的代码:
export interface Farmstype {
aircon: aircontype;
children: Farmstype[];
equips: euiptype[];
latitude: number;
longitude: number;
modDate: string;
name: string;
placeId: number;
placeInfo: placeInfotype;
productCode: string;
productCodeInfo: productCodeInfotypes;
productLifeCycles: productLifeCyclestype[];
roadNameAddress: string;
stnIds: number;
type: string;
}
interface InitialState {
Targetfarms: Farmstype | null;
}
const initialState: InitialState = {
Targetfarms: null,
};
const postSlice = createSlice({
name: "post",
initialState,
reducers: {
// targetLoadFarm
targetFarm(state, action: PayloadAction<Farmstype>) {
state.Targetfarms = action.payload;
},
}
MainPage主页
const MainPage = () => {
const { Targetfarms} = useSelector((state: RootState) => state.post);
console.log("Targetfarms:", Targetfarms?.placeId); // Targetfarms is possibly null,
}
An idea to get rid of optional chaining with you current setup would be to statically type the state of the world and write different components.摆脱当前设置的可选链接的一个想法是静态键入世界的 state 并编写不同的组件。
Not sure I structured your store correctly but you get the idea.不确定我是否正确构建了您的商店,但您明白了。
type RootState = {
app: 'init' | 'running' // we model the state of the app
post: {
Targetfarms: Farmstype | null
}
}
// We dispatch to the correct implementation depending on the state of the world
const MainPage = () =>
useSelector({ app }: RootState) => app) === 'running'
? RunningPage()
: InitPage();
const RunningPage = () => {
const { Targetfarms } = useSelector((state: RunningState) => state.post);
// OK
const f = Targetfarms.placeId
}
const InitPage = () => {
const { Targetfarms } = useSelector((state: InitState) => state.post);
// @ts-expect-error: Targetfarms is possibly null
const f = Targetfarms.placeId
}
There are many ways to produce the different states.有许多方法可以产生不同的状态。 This is an option.
这是一个选项。
// When the app is 'running' `post/Targetfarms` is unlocked
type RunningState = Unlock<RootState, ['post', 'Targetfarms']> & {
state: 'running'
};
// Otherwise Targetfarms is still nullable
type InitState = RootState & {
state: 'init'
};
type Unlock<State, Path extends PropertyKey[]> = unknown & {
[K in keyof State]: Path['length'] extends 1
? K extends Path[0] ? NonNullable<State[K]> : State[K]
: Unlock<
State[K],
Path extends [PropertyKey, ...infer U] ? U & PropertyKey[] : never
>
}
This solution can start to become interesting if you have few app
states and lots of nullable pieces of state. Basically you take the decision of what state the app is in once at the root instead of many times where the values are needed.如果您的
app
状态很少,而 state 有很多可为 null 的部分,那么此解决方案可能会开始变得有趣。基本上,您可以在根目录中一次性决定应用程序在 state 中的位置,而不是多次在需要值的位置。
Maybe that you are trying to access a property of an object that may be null or undefined before the initialization.也许您正在尝试访问 object 的属性,该属性在初始化之前可能是 null 或未定义。 To avoid this error, you have a few options:
为避免此错误,您有以下几种选择:
You can check if the object is null or undefined before trying to access its properties.在尝试访问其属性之前,您可以检查 object 是 null 还是未定义。 For example:
例如:
if (Targetfarms) {
console.log(Targetfarms.placeId);
}
You can set a default value for Targetfarms using the ||您可以使用 || 为 Targetfarms 设置默认值operator.
操作员。 For example:
例如:
const {Targetfarms} = useSelector((state: RootState) => state.post) || {};
console.log(Targetfarms.placeId);
This will set the default value of Targetfarms to an empty object, which means you can access its properties without getting an error.这会将 Targetfarms 的默认值设置为空 object,这意味着您可以访问其属性而不会出现错误。
Note: I think and it's only my opinion here, optional chaining it's a good approach to avoid null or undefined.注意:我认为并且这只是我的意见,可选链接是避免 null 或未定义的好方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.