在Typescript中,可以使用字符串枚举创建记录类型:
enum AxisLabel { X = "X", Y = "Y" }
export const labelLookup: Record<AxisLabel, string> = {
[AxisLabel.X]: "X axis",
[AxisLabel.Y]: "Y Axis"
};
Run Code Online (Sandbox Code Playgroud)
我需要创建一个Record与上述对象类似的对象,但是我不希望使用字符串enum。
当我尝试这样的事情:
enum AxisLabel { X, Y }
export const labelLookup: Record<AxisLabel, string> = {
[AxisLabel.X]: "X axis",
[AxisLabel.Y]: "Y Axis"
};
Run Code Online (Sandbox Code Playgroud)
Typescript产生以下错误:
Type 'AxisLabel' does not satisfy the constraint 'string'.
可以使用数字和字符串作为成员名称来创建JS对象。
我希望在Typescript中做同样的事情,但不要求助于不安全的强制或强制类型转换。如何在Typescript中创建数字枚举Record <>类型而不使用字符串枚举any或类型转换?
更新:TypeScript 2.9 添加了对number和symbol作为有效键类型的支持,因此,只要您使用的是TypeScript 2.9或更高版本,上面的代码就不会再出现错误,并且不再需要此答案。
对于TypeScript 2.8及以下版本:
不管您相信与否,JavaScript中的对象键始终是字符串(可以Symbol是s),即使是数组也是如此。当您将非字符串值作为键传递时,它将首先被强制为字符串。但是人们当然希望数字键有意义,尤其是对于数组。打字稿样的反映了这种不一致的理念:通常你只能指定字符串值的键(如在映射类型一样Record<K,V>)。当这些情况相互作用时,您会变得很奇怪。
这是我有时要做的一件事:使用以下元组类型显式表示从数字到字符串的强制转换:
export type NumericStrings = ["0","1","2","3","4","5","6","7","8","9","10"] // etc
Run Code Online (Sandbox Code Playgroud)
请注意,您可以根据需要延长该时间。然后,您可以使用查找类型将数字类型转换为其对应的字符串,以用于映射类型。像这样:
export enum AxisLabel { X, Y }
// note the key is NumericStrings[AxisLabel], not AxisLabel
export const labelLookup: Record<NumericStrings[AxisLabel], string> = {
[AxisLabel.X]: "X axis",
[AxisLabel.Y]: "Y Axis"
};
Run Code Online (Sandbox Code Playgroud)
那没有错误。如果检查的类型labelLookup,它将显示为Record<"0" | "1", string>。当您尝试索引到时labelLookup,会发生以下预期的事情:
labelLookup[AxisLabel.X]; // okay
labelLookup[0]; // okay
labelLookup["0"]; // also okay
labelLookup[10]; // error
labelLookup.X; //error
Run Code Online (Sandbox Code Playgroud)
希望能有所帮助;祝好运!
记录的定义非常具体,键必须可分配给字符串,因此无法Record与数字一起使用,更一般地,映射类型中的键必须是字符串。
您可以使用常规索引签名,但不能将索引签名限制为除字符串或数字之外的任何内容(根据语言规范),这意味着任何数字都有效,而不仅仅是枚举值:
export const labelLookup: { [index: number]: string } = {
[AxisLabel.X]: "X axis",
[AxisLabel.Y]: "Y Axis",
[3] = "" // Also works but you don't want that
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3285 次 |
| 最近记录: |