[英]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
。 這允許propName
比keyof ICase
更具體。 例如,如果您將"caseDetails"
作為propName
傳入,編譯器將推斷K
是字符串文字類型"caseDetails"
。
請注意, payload
的類型是索引訪問類型ICase[K]
,這意味着ICase
在K
類型的鍵上的屬性類型。 所以如果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.