[英]How to declare object literal as Record with implicit keys
If a constant object literal is created without declaring a type, it will infer the keys from the value:如果在没有声明类型的情况下创建了一个常量对象文字,它将从值中推断出键:
const OBJ = {foo: 42, bar: 42}
This will become a Record<'foo' | 'bar', number>
这将成为一个
Record<'foo' | 'bar', number>
Record<'foo' | 'bar', number>
, which means IDEs will be helpful to offer auto-completion when typing OBJ.fo
etc. Record<'foo' | 'bar', number>
,这意味着 IDE 将有助于在键入OBJ.fo
等时提供自动完成OBJ.fo
。
If the same object is declared like this:如果同一个对象是这样声明的:
const OBJ: Record<string, number> = {foo: 42, bar: 42}
then IDEs will pretend not to know that OBJ
has keys foo
and bar
, since OBJ
is a record of any string key.那么 IDE 会假装不知道
OBJ
有键foo
和bar
,因为OBJ
是任何字符串键的记录。 :( :(
Now, if the values are simple primitives, omitting the type and relying on implicit inferred types usually works fine, but if the record is more complex, such as a Record<string, MyEnum>
or Record<string, (x: string, y: number) => number>
etc, doing so will lose the type information of the values :现在,如果值是简单的原语,省略类型并依赖隐式推断类型通常可以正常工作,但如果记录更复杂,例如
Record<string, MyEnum>
或Record<string, (x: string, y: number) => number>
等,这样做会丢失值的类型信息:
enum MyEnum {
A = 42,
B = 85
}
const OBJ = {foo: A, bar: B};
Now OBJ
will be a Record<'foo' | 'bar', number>
现在
OBJ
将是一个Record<'foo' | 'bar', number>
Record<'foo' | 'bar', number>
, not a Record<'foo' | 'bar', MyEnum>
Record<'foo' | 'bar', number>
,不是Record<'foo' | 'bar', MyEnum>
Record<'foo' | 'bar', MyEnum>
. Record<'foo' | 'bar', MyEnum>
。
What I want is to declare a dictionary where the type of the values is given in the declaration, but keys are inferred.我想要的是声明一个字典,其中在声明中给出了值的类型,但推断出键。
The only ways I've found are:我发现的唯一方法是:
const OBJ = {foo: <MyEnum>A, bar: <MyEnum>B};
type Keys = 'foo' | 'bar';
const OBJ: Record<Keys, MyEnum> = {foo: A, bar: B};
Is there a better way, where the keys are inferred by the literal but the values are declared on the entire Record
?有没有更好的方法,键是由文字推断的,但值是在整个
Record
上声明的?
I am not sure which TypeScript version you are using.我不确定您使用的是哪个 TypeScript 版本。 Also, your example has an error, you need to use
MyEnum.A
instead of just A
.此外,您的示例有一个错误,您需要使用
MyEnum.A
而不仅仅是A
。
Let's look at your example:让我们看看你的例子:
enum MyEnum {
A = 42,
B = 85
}
const OBJ = {foo: MyEnum.A, bar: MyEnum.B};
OBJ
has the correct type: { foo: MyEnum; bar: MyEnum; }
OBJ
具有正确的类型: { foo: MyEnum; bar: MyEnum; }
{ foo: MyEnum; bar: MyEnum; }
{ foo: MyEnum; bar: MyEnum; }
. { foo: MyEnum; bar: MyEnum; }
. Tested in 3.9 >
typescript.在
3.9 >
打字稿中测试。
Try on TS Playground试玩TS Playground
Regarding your requirements:关于您的要求:
What I want is to declare a dictionary where the type of the values is given in the declaration, but keys are inferred.
我想要的是声明一个字典,其中在声明中给出了值的类型,但推断出键。
You can use Generics function to infer type:您可以使用泛型函数来推断类型:
enum MyEnum {
A = 42,
B = 85
}
function fixType<T extends string>(value: Record<T, MyEnum>): Record<T, MyEnum> {
return value
}
const OBJ = fixType({foo: MyEnum.A, bar: MyEnum.B})
And now OBJ
has Record<"foo" | "bar", MyEnum>
现在
OBJ
有Record<"foo" | "bar", MyEnum>
Record<"foo" | "bar", MyEnum>
type. Record<"foo" | "bar", MyEnum>
类型。
Try on TS Playground试玩TS Playground
If you are using Enum
, you may be interested in this issue .如果您正在使用
Enum
,您可能会对这个问题感兴趣。 To sum up, even if you specified which numbers your enum supports, TS still allows assigning any number...总而言之,即使您指定了您的枚举支持哪些数字,TS 仍然允许分配任何数字...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.