英文:
Typescript. When properties are enum values, they are treated as read only
问题
因为它是一个只读属性。
英文:
On this code:
enum SpeedRanges {
slow,
fast,
}
type SpeedHistogram = {
[key in keyof typeof SpeedRanges]?: number;
};
const sh: SpeedHistogram = {};
sh.slow = 9;
I get this error:
> Cannot assign to 'slow' because it is a read-only property.(2540)
Why is it read only?
答案1
得分: 3
这似乎起作用。
英文:
This seems to do the trick.
enum SpeedRanges {
slow,
fast,
}
type SpeedRangeKey = keyof typeof SpeedRanges;
type SpeedHistogram = {
[key in SpeedRangeKey]?: number;
};
const sh: SpeedHistogram = {};
sh.slow = 9;
答案2
得分: 2
在TypeScript中,枚举是只读的,这完全有道理。
有两种可能的解决方案:
- 使用映射修饰符移除
readonly
修饰符:
type SpeedHistogram = {
-readonly [key in keyof typeof SpeedRanges]?: number;
};
然而,枚举包含索引签名[x: number]: number
:
type SpeedHistogram = {
[x: number]: number | undefined;
slow?: number | undefined;
fast?: number | undefined;
}
使用索引签名,可以添加任何数字键及其对应的数字值。我们可以通过仅获取枚举的字符串键来移除索引签名,这可以使用内置实用类型Extract或使用string
与键进行交集操作来实现,这等同于任何字符串键:
type SpeedHistogram = {
-readonly [Key in (keyof typeof SpeedRanges) & string]?: number;
};
- 为
SpeedRanges
的键定义一个单独的类型:
type SpeedRangesKeys = keyof typeof SpeedRanges;
type SpeedHistogram = {
[Key in SpeedRangesKeys]?: number;
};
单独类型起作用的原因是,在原始版本中,keyof
被用在映射类型内部,从而获取属性修饰符(readonly
)并应用于属性。在定义单独类型时,没有上下文,因此我们只获取所有键的联合,没有任何修饰符。
英文:
Enums in typescript are read-only which totally makes sense.
There are two possible solutions:
- Remove the
readonly
modifier using mapping modifiers:
type SpeedHistogram = {
-readonly [key in keyof typeof SpeedRanges]?: number;
};
However, enums contain index signature of [x: number]: number
:
type SpeedHistogram = {
[x: number]: number | undefined;
slow?: number | undefined;
fast?: number | undefined;
}
With an index signature, you can add any number key with a number value. We can remove the index signature by only taking the string keys of the enum, which can be done either by using the built-in utility type Extract or by interesting the keys with string
, which will only take the intersection, which is equivalent to any string key:
type SpeedHistogram = {
-readonly [Key in (keyof typeof SpeedRanges) & string]?: number;
};
- Define a separate type for the keys of the
SpeedRanges
:
type SpeedRangesKeys = keyof typeof SpeedRanges;
type SpeedHistogram = {
[Key in SpeedRangesKeys]?: number;
};
The reason why the separate type works are because in the OP version, the keyof
is used inside of the mapped type which gets the property modifier (readonly
) and applies to the property. When defining a separate type there is no context so we just get the union of all keys without any modifiers.
答案3
得分: 1
在TypeScript中,枚举是readonly
的。当你直接遍历键来定义其他键时,新定义的键也会继承原始键的属性,因为它们是readonly
属性。
如果你想移除readonly
属性,只需使用-readonly
修改器,如下所示:
enum SpeedRanges {
slow,
fast,
}
type SpeedHistogram = {
-readonly [key in keyof typeof SpeedRanges]?: number;
};
const sh: SpeedHistogram = {};
sh.slow = 9;
你也可以使用@IgorDanchenko的答案,他使用原始键列表来定义一个字符串联合,这个联合只是一组字符串,它们没有任何属性。
英文:
In TypeScript enums are readonly
. When you iterate over the keys directly to define another keys, you also inherit the original key properties in the newly defined keys, as the readonly
property.
If you want to remove the readonly
property, just use -readonly
modificator, like so:
enum SpeedRanges {
slow,
fast,
}
type SpeedHistogram = {
-readonly [key in keyof typeof SpeedRanges]?: number;
};
const sh: SpeedHistogram = {};
sh.slow = 9;
You can also use @IgorDanchenko's answer, which is using the original key list to define a string union, which being just a list of strings, they do not have any properties in them.
答案4
得分: 0
可能你正在尝试使用数字枚举,但你想要的是字符串枚举。
enum SpeedRanges {
slow = "slow",
fast = "fast",
}
type SpeedHistogram = {
[key in SpeedRanges]?: number;
};
const sh: SpeedHistogram = {};
sh.slow = 9;
英文:
It's possible that you are trying to use number enum when you want a string enum
enum SpeedRanges {
slow = "slow",
fast = "fast",
}
type SpeedHistogram = {
[key in SpeedRanges]?: number;
};
const sh: SpeedHistogram = {};
sh.slow = 9;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论