简体   繁体   English

如何避免 Typescript 中的可选链接?

[英]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组件中使用带有TargetfarmsuseSelector并且我想使用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.

相关问题 当我使用 JavaScript 时,如何在 object 数据中使用可选链接? - How can I use optional chaining in object data when I use JavaScript? 使用React + TypeScript,当使用启用了strictNullChecks的默认值的可选道具时,如何避免类型转换? - With React + TypeScript, how do I avoid typecasting when using optional props with defaults with strictNullChecks enabled? 我们应该使用吗? 或者。? 打字稿中的(可选链接)? - Should we using ! or ?. (optional chaining) in typescript? 如何使用 React useRef 避免 TypeScript 错误? - How can I avoid a TypeScript error with React useRef? 如何避免 redux Typescript 中的任何类型 - How can I avoid any type in redux Typescript 如何添加 TypeScript 3.7 Optional Chaining 支持以创建 React 应用程序项目 - How to add TypeScript 3.7 Optional Chaining support to create react app project Typescript 可选链结合三元运算符解析错误 - Typescript optional chaining combined with ternary operator parsing error 如何修复 React 项目的可选链接错误? - How to fix Optional chaining Error on React project? 如何在 typescript 中有条件地使接口中的字段成为可选或必需? - How do i make a field in an interface conditionaly optional or required in typescript? 我应该如何 go 关于 TypeScript 中的方法链接(就像 Tiptap 的做法一样) - How should I go about method chaining in TypeScript (like how Tiptap does it)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM