繁体   English   中英

如何使用隐式键将对象文字声明为记录

[英]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有键foobar ,因为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>

我想要的是声明一个字典,其中在声明中给出了值的类型,但推断出键。

我发现的唯一方法是:

  1. 键入每个
const OBJ = {foo: <MyEnum>A, bar: <MyEnum>B};
  1. 单独声明键
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 >打字稿中测试。

试玩TS Playground


关于您的要求:

我想要的是声明一个字典,其中在声明中给出了值的类型,但推断出键。

您可以使用泛型函数来推断类型:

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})

现在OBJRecord<"foo" | "bar", MyEnum> Record<"foo" | "bar", MyEnum>类型。

试玩TS Playground


如果您正在使用Enum ,您可能会对这个问题感兴趣。 总而言之,即使您指定了您的枚举支持哪些数字,TS 仍然允许分配任何数字...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM