簡體   English   中英

如何在 useReducer 中使用具有必填字段的泛型類型?

[英]How to use generic types with required fields in useReducer?

我正在嘗試使用 useReducer 創建自定義 React 鈎子。 它應該保存對象數組的狀態,並且所有對象都必須有一個“id”字段。 id 以外的對象結構應該是通用的。

這是我所擁有的;

export enum ArrayActions { INIT, ADD, UPDATE, DELETE }

type ArrayAction<T> =
  | { type: ArrayActions.INIT, payload: T[] }
  | { type: ArrayActions.ADD, payload: T }
  | { type: ArrayActions.UPDATE, payload: T }
  | { type: ArrayActions.DELETE, id: string }

type ObjWithId = { id:any, [key: string]: any }

function arrayReducer<T extends ObjWithId>(state: T[], action: ArrayAction<T>): T[] {
  switch(action.type){
    case ArrayActions.INIT:
      return [...action.payload]
    case ArrayActions.ADD: // TODO: check if id already exists
      return [...state, action.payload]
    case ArrayActions.UPDATE:
      return [...(state.filter(item => item.id !== action.payload.id)), action.payload]
    case ArrayActions.DELETE:
      return state.filter(item => item.id !== action.id)
  }
}

export function useArrayReducer<T extends ObjWithId> (initialState: T[] = []): [T[], React.Dispatch<ArrayAction<T>>] {
  const [state, dispatch] = useReducer(arrayReducer, initialState)
  return [state, dispatch]      // error!
}

最后一行中的state給出了以下錯誤;

Type 'ObjWithId[]' is not assignable to type 'T[]'.
Type 'ObjWithId' is not assignable to type 'T'.

我認為這可能與ObjWithId ,但無法完全弄清楚。 你能幫我達到想要的結果嗎?

萬一有人需要它;

export interface ListItem { 
  id: string | number | undefined;
  [key: string]: any;
}

export type Action<L extends ListItem> = 
  | { type: "init", items: L[]}
  | { type: "add", item: L }
  | { type: "update", item: L }
  | { type: "delete", id: NonNullable<L["id"]>}

暫無
暫無

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

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