簡體   English   中英

如何制作類型安全的泛型 function

[英]How can I make a typesafe generic function

我認為這是可能的,但我在搜索正確的關鍵字時遇到了問題。 我有一個用於設置 object 的多個屬性的方法,我希望它類型安全。

interface ICase {
  caseDetails: ICaseDetails;
  observations: IObservations;
}
interface ICaseDetails {
  a: string;
}
interface IObservations {
  b: number;
}

const updateCasePart = (state: ICase, payload: any, propName: keyof ICase) => { 
  state[propName] = payload
}

有沒有一種方法可以輸入有效負載,以便將調用 function 限制為正確的有效負載類型? 我知道我可以做payload: ICaseDetails | IObservations payload: ICaseDetails | IObservations但我希望得到類似payload: typeof keyof ICase的東西

正如您的標題所暗示的那樣,您應該按如下方式使 function通用

const updateCasePart = <K extends keyof ICase>(
  state: ICase, payload: ICase[K], propName: K
) => { state[propName] = payload }

我們沒有將propName參數注釋keyof ICase類型(相當於聯合類型"caseDetails" | "observations" ),而是將其注釋為通用類型K ,該類型已被限制keyof ICase 這允許propNamekeyof ICase更具體 例如,如果您將"caseDetails"作為propName傳入,編譯器將推斷K是字符串文字類型"caseDetails"

請注意, payload的類型是索引訪問類型ICase[K] ,這意味着ICaseK類型的鍵上的屬性類型。 所以如果K"caseDetails" ,那么ICase[K]就是ICaseDetails 這(主要)確保您為payload傳遞的值是合適的。

賦值state[propName] = payload type 檢查是因為編譯器將賦值的兩邊視為相同的通用類型ICase[K]


讓我們測試一下:

declare const caseDetails: ICaseDetails;
declare const observations: IObservations;
declare const state: ICase;

updateCasePart(state, caseDetails, "caseDetails"); // okay
updateCasePart(state, caseDetails, "observations"); // error!
// -----------------> ~~~~~~~~~~~
// Argument of type 'ICaseDetails' is not assignable to parameter of type 'IObservations'.
updateCasePart(state, observations, "observations"); // okay

看起來不錯。 編譯器允許有效調用並且(大部分)不允許無效調用。


好吧,我一直說“大部分”。 有一個類型安全漏洞 generics 涉及工會; 如果出於某種奇怪的原因你傳入了一個類型為鍵類型聯合的propName參數,那么K將被推斷為該聯合,並且ICase[K]也將是一個聯合,這意味着可能允許錯誤調用:

updateCasePart(state, caseDetails,
  Math.random() < 0.99 ? "observations" : "caseDetails"
); // okay?!

上面沒有錯誤,但是有 99% 的可能性你已經將"observations"作為propName傳遞給ICaseDetails作為payload

如果它真的很重要,可以開始重寫updateCasePart以減少此類事情發生的可能性......但是由於TypeScript 不是完全類型安全的,你不能真正阻止每一個可能的不安全操作,並且付出更多的努力會減少回報。

對於大多數用途,像上面這樣的通用 function 提供了足夠的安全性和可用性,因此我不會在這里進一步離題,詳細說明在通往純粹穩健性的無盡且越來越危險的無盡道路上可能發生的偏移。

游樂場代碼鏈接

暫無
暫無

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

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