只读修饰符在扩展类时不传播?(打字稿)



我正在尝试在TS中创建只读接口,下面是我尝试过的readonly修饰符传播到子类型的示例:

type JsonDatum =
| string
| boolean
| number
| readonly Json[]
| Object
| null
| undefined;
interface JsonInterface {
readonly [key: string]: Json;
}
type Json = JsonDatum | JsonInterface;
interface Player extends JsonInterface {
name: string;
countryCodes: number[];
elo: number;
}
const player: Player = {
name: "John Doe",
countryCodes: [1, 2, 3],
elo: 2000
}
player.name = "123"      // No problem
player.countryCodes = [] // No problem

我认为,通过在JsonInterface中添加readonly修饰符,扩展它的接口也将具有其属性readonly。但是没有问题。

为了使它发挥作用,我不得不采取这种非常非DRY的方法,并手动将readonlys添加到子类型的所有属性中:

...
interface Player extends JsonInterface {
readonly name: string;
readonly countryCodes: number[];
readonly elo: number;
}
...
player.name = "123"      // Cannot assign to 'name' because it is a read-only property.(2540)
player.countryCodes = [] // Cannot assign to 'name' because it is a read-only property.(2540)

这是TypeScript操场上的代码。

我想我会将我的方法转换为Readonly<T>泛型,因为它似乎是更推荐的路径,但即使这样,似乎也存在问题。

(Readonly<T>的定义似乎接近于我正在做的:type Readonly<T> = { readonly [P in keyof T]: T[P]; }。我确实尝试用Readonly<T>来调整上面的例子,但没有成功。(

这是预期的行为吗?是否有没有Readonly<T>的变通方法?

这是预期的行为,正如您在这里看到的,Person可以被认为是"覆盖";CCD_ 12中的定义。在这个修改后的例子中,效果更加明显。

这里很容易看出,即使JsonInterface定义了readonly namePerson接口也会覆盖它

文档中有用的摘录:

接口上的extends关键字允许我们有效地复制其他命名类型的成员,并添加我们想要的任何新成员。这对于减少我们必须编写的类型声明样板文件的数量,以及发出同一属性的几个不同声明可能相关的意图非常有用。

真的没有容易的"变通办法";为此,但无论如何都应该使用Readonly<T>(这就是它的用途!(。致";让它发挥作用";使用Readonly,您可以尝试:

type Player = Readonly<{
name: string;
countryCodes: number[];
elo: number;
}>;

您可以在这里看到,结果是所需的类型。

相关内容

  • 没有找到相关文章

最新更新