TypeScript-可索引类型扩展的keyof的穷举检查

TypeScript-可索引类型扩展的keyof的穷举检查,typescript,types,Typescript,Types,我遇到一个问题,当keyof操作符用于扩展可索引类型的类型时,TypeScript没有彻底检查类型 因此,keyof操作符的正常用例类似于Pick类型: 接口人{ 名称:字符串; 年龄:人数; 活动:布尔; } 函数getPersonInfo(person:person,prop:K):person[K]{ 返回人[道具]; } getPersonInfo({姓名:“约翰”,年龄:31,活着的:真的},“年龄”);//编译并返回31 getPersonInfo({姓名:“约翰”,年龄:31,活着

我遇到一个问题,当
keyof
操作符用于扩展可索引类型的类型时,TypeScript没有彻底检查类型

因此,keyof操作符的正常用例类似于
Pick
类型:

接口人{
名称:字符串;
年龄:人数;
活动:布尔;
}
函数getPersonInfo(person:person,prop:K):person[K]{
返回人[道具];
}
getPersonInfo({姓名:“约翰”,年龄:31,活着的:真的},“年龄”);//编译并返回31
getPersonInfo({姓名:“约翰”,年龄:31,活着:真的,},“ssn”);//未编译,因为“ssn”与“name”|“age”|“alive”的类型不匹配
但是,当涉及可索引类型时,我们不再获得
keyof
的这种安全性(即编译时错误,告诉我们提供的参数不是所讨论类型的键)。例如:

接口集合{
[项目:字符串]:任何;
}
接口MyCollection扩展了集合{
东西:绳子,
什穆林:布尔,
木材:数量
}
函数getInfo(集合:C,键:K):C[K]{
返回集合[键];
}
设c:MyCollection=未定义为与MyCollection一样未知;
getInfo(c,“某物”);//即使“某物”不是MyCollection的属性,也会编译
现在,我想我理解了为什么会发生这种情况,我相信这是因为在扩展可索引类型的接口上,“可索引签名”(如果您愿意)仍然存在于类型上,这意味着
keyof
返回的类型有效地扩展到
string

那么我的问题是有没有办法防止这种情况发生?为了在我的类型系统中使用它们,我需要能够用它们的父可索引类型标记类,所以我不能仅仅消除可索引类型,但我还希望能够彻底检查提供给
keyof
类型的参数的类型,并在使用非键时给出编译时错误

EDIT1:我发现了一个关于通过使用一个不可靠的类型从类型中删除索引签名的方法:

类型KnownKeys={
[K in keyof T]:字符串扩展K?从不:数字扩展K?从不:K
}扩展{[U]in keyof T]:推断U}?U:从来没有;
因此,新功能实际上是:

函数getInfo(集合:C,键:K):C[K]{ 返回集合[键]; } 我认为这是我需要走的方向,但现在我有两个相关的问题:

  • 我刚才给出的示例没有编译,失败了,错误告诉我类型
    C
    不能被类型
    KnownKeys
    索引,或者它将类型缩小为
    未知的
    。。。我通过对返回类型使用如下条件类型解决了这个问题:
  • K扩展了keyc的功能?C[K]:永远不会
    
  • 这似乎仍然不允许TypeScript编译器彻底检查
    keyof
    的类型