Typescript 在不丢失类型的情况下检查常量文本的键

Typescript 在不丢失类型的情况下检查常量文本的键,typescript,Typescript,我想要一个引用接口键的常数。 我希望对这个常量进行类型检查,以确保键的名称正确,并且我还希望将它们作为文本进行类型化 如果我这样做: 接口MyInterface{ keyA:字符串; 键B:字符串; } 导出常量MY_键:记录={ 常量键A:“键A”, 常数键:“键”, }作为常量; 我的钥匙。恒定的钥匙 然后MY_KEY.常量_KEY_A的类型为'keyA'|'keyB'。但我希望它是'keyA' 如果我删除记录,那么它将起作用,但是我的密钥不再被类型检查为位于MyInterface的密钥中

我想要一个引用接口键的常数。 我希望对这个常量进行类型检查,以确保键的名称正确,并且我还希望将它们作为文本进行类型化

如果我这样做:

接口MyInterface{
keyA:字符串;
键B:字符串;
}
导出常量MY_键:记录={
常量键A:“键A”,
常数键:“键”,
}作为常量;
我的钥匙。恒定的钥匙
然后
MY_KEY.常量_KEY_A
的类型为
'keyA'|'keyB'
。但我希望它是
'keyA'

如果我删除
记录
,那么它将起作用,但是我的密钥不再被类型检查为位于MyInterface的密钥中

你知道我怎样才能做到吗

例如,我可以添加第二个死变量来执行记录检查,并将第一个死变量仅保留为const,而不是强制转换为Record,但它非常冗长,也不太清楚


谢谢大家!

在这种情况下,我通常会引入一个helper函数,该函数检查某个值是否可分配给某个类型,而不会将该值扩大到该类型。helper函数的常规版本如下所示:

const checkType = <T>() => <U extends T>(u: U) => u;
但该函数的输出未按要求加宽:

MY_KEYS.CONSTANT_KEY_A // "keyA"
请注意,您甚至不需要将
作为常量
,因为编译器认为您希望将对象文字解释为可分配给
记录
,因此不会将文字字符串值扩大到
字符串
。不过,如果它在其他方面对您有所帮助,您仍然可以将
用作const


从概念上讲,这与您的“死变量”想法并没有什么不同,当然在运行时
(()=>u=>u)()(someValue)
是一种编写
someValue
的奇怪方式。但是,如果在TypeScript中没有内置的“verifyassignability而不加宽”操作符(比如maybe?),这通常是我知道的最好的方法

好吧,希望这会有帮助;祝你好运


非常感谢您的回答!但是它不起作用对不起,
“keyC”
示例导致了这种情况;该错误使编译器放弃了类型推断。我把它注释掉了,现在你会看到值的类型是
“keyA”
。太棒了,它确实有效!非常感谢,它非常适合我的需要
export const MY_KEYS = checkKeys({
  CONSTANT_KEY_A: 'keyA',
  CONSTANT_KEY_B: 'keyB',
  // CONSTANT_KEY_C: 'keyC', // error! '"keyC"' is not assignable to  '"keyA" | "keyB"'.
})
MY_KEYS.CONSTANT_KEY_A // "keyA"