让我们首先为这个过于笼统的问题道歉,但由于缺乏对这里发生的事情的了解,我正在绞尽脑汁如何缩小范围,因此将根据评论/答案进行调整。
我在TypeScript Playground上创建了一个示例程序,该程序不应该编译,但可以编译(在撰写本文时使用最新版本的 TypeScript,v4.5.2)。我试图理解为什么会编译它,以便了解其他不良程序可能会溜过去类型检查器并且不会被发现。这是该程序的另一个版本,显示了运行时的问题。有没有我忽略的选项或者我可以做些什么来让这个程序不进行类型检查?
为了方便起见,我也在此处内联了相关程序:
type Settings = { 'a': boolean; 'b': string }
function setSetting<K extends keyof Settings>(p: K, v: Settings[K]): void {}
// setSetting('a', 100) // good; it fails
setSetting('a', true); // good; compiles
function breakSetSetting(k: keyof Settings, v: boolean): void {
setSetting(k, v);
}
breakSetSetting('b', true); // bad; it compiles!
Run Code Online (Sandbox Code Playgroud)
更新:根据@crashmstr的评论,使用泛型使breakSettings 程序无法编译,但是,我仍然不清楚为什么它之前被允许编译。
当您定义 时K,您将其定义为'a' | 'b'(即keyof K)。这意味着v它将Settings['a' | 'b']评估为boolean | string。现在,当您breakSetSetting将 a 传递boolean给时setSetting,boolean位于 的范围内boolean | string,使编译器通过。