繁体   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