簡體   English   中英

React Typescript 泛型類型重載(例如 useState)

[英]React Typescript Generic Type Overloading (e.g. useState)

我正在嘗試創建一個重載的 function,它將寫入和寫入 session 存儲,而不是標准的 state。 我希望它在我只提供類型而不是初始值的情況下是可重載的。 就像useState在反應中所做的一樣。

這是我到目前為止所擁有的:

export function useSessionState<S = undefined>(initialState?: S): [S, (state: S) => void];
export function useSessionState<S>(initialState: S): [S, (state: S) => void] {
  const [state, setState] = useState<S>()

  // Unimportant: Do something to load to and from session storage.

  return [state, (value) => {

  }]
}

當我嘗試使用這種類型時,我只會得到其中一個重載的結果類型。

// Variable 'state' is a string as expected.
const [state, setState] = useSessionState("some_initial_value")

// Variable 'undefinedState' is also a string, but it should be undefined since no 'initialState' was provided.
const [undefinedState, setUndefinedState] = useSessionState<string>()

我自己也不知道答案,所以我開始閱讀和嘗試。 我的嘗試非常接近,但我發現了以下缺陷:

  • 兩次嘗試都將initialState顯示為類型S而不是S | undefined S | undefined ,這意味着您將努力實現此 function 而不進行強制轉換。
  • 第一個解決方案和第二個解決方案生成的.d.ts是不同的。 我相信第一次嘗試的.d.ts更接近官方的useState定義。
  • 即使你沒有提到它:
    • initialState可以是一個值或一個 function,這只是第二次嘗試的情況。
    • setState function 應該有一個S | undefined S | undefined ,而不是S

希望有更好的解決方案......如果只有實際實現寫在 Typescript 中。

嘗試 1: 條件類型

操場

function useState<S>(initialState: S): [S, (state: S) => void];
function useState<S = undefined>(): [S | undefined, (state: S) => void];
function useState<S = undefined>(initialState?: S): [S extends undefined ? undefined | S : S, (state: S) => void] {
  throw new Error(`Not implemented and not using ${initialState}`);
}

const [state1, setState1] = useState<string>("initialValue"); // string
const [state2, setState2] = useState("initialValue"); // string
const [state3, setState3] = useState<string>(); // undefined | string
const [state4, setState4] = useState(); // undefined

在操場上生成的.d.ts

declare function useState<S>(initialState: S): [S, (state: S) => void];
declare function useState<S = undefined>(): [S | undefined, (state: S) => void];

嘗試 2:沒有條件類型

操場

type Dispatch<T> = (value: T) => void;

function useState<S = undefined>(): [S | undefined, Dispatch<S | undefined>];
function useState<S>(initialState?: S | (() => S)): [S, Dispatch<S>];
function useState<S>(initialState?: S | (() => S)): [S, Dispatch<S>] {
    throw new Error(`Not implemented and not using ${initialState}`);
}
 
const [state1, setState1] = useState<string>("initialValue"); // string
const [state2, setState2] = useState("initialValue"); // string
const [state3, setState3] = useState<string>(); // undefined | string
const [state4, setState4] = useState(); // undefined

在操場上生成的.d.ts

declare function useState<S = undefined>(): [S | undefined, Dispatch<S | undefined>];
declare function useState<S>(initialState?: S | (() => S)): [S, Dispatch<S>];

暫無
暫無

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

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