简体   繁体   English

将类型记录为编译时常量

[英]Record types as compile-time constant

A new-ish addition to TypeScript is the as const clause, which specifies objects and arrays as compile-time, readonly constant values, whose types are atomically specific. TypeScript 的新增功能是as const子句,它将对象和 arrays 指定为编译时只读常量值,其类型是原子特定的。

const x: {
  key: "value"
} as const

is represented by the type由类型表示

readonly { "key": "value" }

This is a superb feature, allowing const object declarations which I can use for other types.这是一个极好的功能,允许我可以将其用于其他类型的const object 声明。 However when I need to declare an map of types as compile-time constants, which extends a Record type, it seems that the as const clause and the Record type have opposite effects.但是,当我需要将类型的 map 声明为扩展Record类型的编译时常量时,似乎as const子句和Record类型具有相反的效果。

enum Enum {
  key1,
  key2,
}

const staticMap: Record<Enum, string> = {
  [Enum.key1]: "value1",
  [Enum.key2]: "value2"
} as const;

yields the type Record<Enum, string> , despite being marked as const .产生类型Record<Enum, string> ,尽管被标记为const Omitting the type gives the correct type annotation, however I lose the restriction to use members of Enum as keys to staticMap .省略类型给出了正确的类型注释,但是我失去了使用Enum的成员作为staticMap的键的限制。

To be honest, I'm not sure how to proceed from here.老实说,我不确定如何从这里开始。 I'm wondering whether's some sort of halfway point, such that the following snippet fails:我想知道是否是某种中间点,以至于以下代码段失败:

const x: <all values must be assignable to `string`> = {
  [Enum.key1]: "string",
  [Enum.key2]: 123
} as const

Thanks for any pointers感谢您的任何指点

If you specify the type of a variable, that is it's final type, so as long as the expression on the right is assignable to it, everything is fine.如果你指定一个变量的类型,也就是它的最终类型,所以只要右边的表达式可以赋值给它,一切都很好。

In this case you might want to remove the as const and specify the fact that the record is readonly:在这种情况下,您可能希望删除as const并指定记录是只读的这一事实:

enum Enum {
  key1,
  key2,
}

const staticMap: Readonly<Record<Enum, string>> = {
  [Enum.key1]: "value1",
  [Enum.key2]: "value2"
};

Playground Link 游乐场链接

The version above does not fully emulate as const .上面的版本没有完全模拟as const If you want to preserve the value types as well you will need to use a generic function to capture the original value passed in for each property.如果您还想保留值类型,则需要使用通用 function 来捕获为每个属性传入的原始值。 This is closer to the behavior of as const :这更接近as const的行为:

enum Enum {
  key1,
  key2,
}

function makeRecord<T extends Record<Enum, V>, V extends string>(o: T): Readonly<T> {
  return o
}
const staticMap = makeRecord({
  [Enum.key1]: "value1",
  [Enum.key2]: "value2"
});


const x: typeof staticMap[Enum.key1] = "value2"; // err

Playground Link 游乐场链接

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

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