簡體   English   中英

如何避免 Typescript 中的可選鏈接?

[英]How can I avoid optional chaining in Typescript?

我試圖在 redux 中存儲名為Targetfarms的 object 數據。我為Targetfarms分配了一個名為Farmstype的類型。

但是,當我在MainPage組件中使用帶有TargetfarmsuseSelector並且我想使用targetfarm.aircon時,如果我不在Targetfarms中使用可選鏈接,則會發生此錯誤。

Targetfarms is possibly null,

如果我使用optional chaining,我可以正常獲取Targetfarms數據,但我不想盡可能使用optional chaining。

我該如何修復我的代碼?

這是我的代碼:

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;
        },
    }

主頁

const MainPage = () => {
    const { Targetfarms} = useSelector((state: RootState) => state.post);

    console.log("Targetfarms:", Targetfarms?.placeId);    // Targetfarms is possibly null,

}

擺脫當前設置的可選鏈接的一個想法是靜態鍵入世界的 state 並編寫不同的組件。

不確定我是否正確構建了您的商店,但您明白了。

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

}

有許多方法可以產生不同的狀態。 這是一個選項。

// 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
        >
}

如果您的app狀態很少,而 state 有很多可為 null 的部分,那么此解決方案可能會開始變得有趣。基本上,您可以在根目錄中一次性決定應用程序在 state 中的位置,而不是多次在需要值的位置。

也許您正在嘗試訪問 object 的屬性,該屬性在初始化之前可能是 null 或未定義。 為避免此錯誤,您有以下幾種選擇:

在嘗試訪問其屬性之前,您可以檢查 object 是 null 還是未定義。 例如:

if (Targetfarms) {
  console.log(Targetfarms.placeId);
}

您可以使用 || 為 Targetfarms 設置默認值操作員。 例如:

const {Targetfarms} = useSelector((state: RootState) => state.post) || {};
console.log(Targetfarms.placeId);

這會將 Targetfarms 的默認值設置為空 object,這意味着您可以訪問其屬性而不會出現錯誤。

注意:我認為並且這只是我的意見,可選鏈接是避免 null 或未定義的好方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM