我试图在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我认为,通过将readonly修饰符添加到JsonInterface中,扩展它的接口也将具有其属性readonly。但没什么问题。
为了使其工作,我不得不采用这种非常不枯燥的方法,并手动将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)这里是打字稿操场上的代码。
我想我要将我的方法转换为Readonly<T>泛型,因为它似乎是更推荐的路径,但是即使这样,似乎也有问题。。
( Readonly<T>的定义似乎与我所做的非常接近:type Readonly<T> = { readonly [P in keyof T]: T[P]; }。我确实尝试过用Readonly<T>来修改上面的例子,但是没有成功。)
这是预期的行为吗?没有Readonly<T>有解决办法吗?
发布于 2022-09-11 05:08:58
这是预期的行为,正如您可以看到的这里,Person可以被认为是“覆盖”JsonInterface中的定义。在这个修正示例中,效果更明显。
在这里可以很容易地看到,即使JsonInterface定义了readonly name,Person接口也会覆盖它。
文档的一个有用的摘录
接口上的
extends关键字允许我们有效地从其他命名类型复制成员,并添加我们想要的任何新成员。这对于减少我们必须编写的类型声明模板的数量,以及表明几个相同属性的不同声明可能相关的意图都是有用的。
对于这一点,没有简单的“解决办法”,但无论如何您都应该使用Readonly<T> (这就是它的目的!)要使用Readonly“使其工作”,您可以尝试:
type Player = Readonly<{
name: string;
countryCodes: number[];
elo: number;
}>;您可以看到这里,结果是所需的类型。
https://stackoverflow.com/questions/73673572
复制相似问题