TypeScript。当属性是枚举值时,它们被视为只读。

huangapple go评论63阅读模式
英文:

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中,枚举是只读的,这完全有道理。
有两种可能的解决方案:

  1. 使用映射修饰符移除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;
};
  1. 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:

  1. 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;
};
  1. 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;

huangapple
  • 本文由 发表于 2023年7月7日 03:52:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76632155.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定