![](/img/trans.png)
[英]Declare object with keys constrained to be element of object literal
[英]How to declare object literal as Record with implicit keys
如果在没有声明类型的情况下创建了一个常量对象文字,它将从值中推断出键:
const OBJ = {foo: 42, bar: 42}
这将成为一个Record<'foo' | 'bar', number>
Record<'foo' | 'bar', number>
,这意味着 IDE 将有助于在键入OBJ.fo
等时提供自动完成OBJ.fo
。
如果同一个对象是这样声明的:
const OBJ: Record<string, number> = {foo: 42, bar: 42}
那么 IDE 会假装不知道OBJ
有键foo
和bar
,因为OBJ
是任何字符串键的记录。 :(
现在,如果值是简单的原语,省略类型并依赖隐式推断类型通常可以正常工作,但如果记录更复杂,例如Record<string, MyEnum>
或Record<string, (x: string, y: number) => number>
等,这样做会丢失值的类型信息:
enum MyEnum {
A = 42,
B = 85
}
const OBJ = {foo: A, bar: B};
现在OBJ
将是一个Record<'foo' | 'bar', number>
Record<'foo' | 'bar', number>
,不是Record<'foo' | 'bar', MyEnum>
Record<'foo' | 'bar', MyEnum>
。
我想要的是声明一个字典,其中在声明中给出了值的类型,但推断出键。
我发现的唯一方法是:
const OBJ = {foo: <MyEnum>A, bar: <MyEnum>B};
type Keys = 'foo' | 'bar';
const OBJ: Record<Keys, MyEnum> = {foo: A, bar: B};
有没有更好的方法,键是由文字推断的,但值是在整个Record
上声明的?
我不确定您使用的是哪个 TypeScript 版本。 此外,您的示例有一个错误,您需要使用MyEnum.A
而不仅仅是A
。
让我们看看你的例子:
enum MyEnum {
A = 42,
B = 85
}
const OBJ = {foo: MyEnum.A, bar: MyEnum.B};
OBJ
具有正确的类型: { foo: MyEnum; bar: MyEnum; }
{ foo: MyEnum; bar: MyEnum; }
{ foo: MyEnum; bar: MyEnum; }
. 在3.9 >
打字稿中测试。
关于您的要求:
我想要的是声明一个字典,其中在声明中给出了值的类型,但推断出键。
您可以使用泛型函数来推断类型:
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})
现在OBJ
有Record<"foo" | "bar", MyEnum>
Record<"foo" | "bar", MyEnum>
类型。
如果您正在使用Enum
,您可能会对这个问题感兴趣。 总而言之,即使您指定了您的枚举支持哪些数字,TS 仍然允许分配任何数字...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.