gpt4 book ai didi

javascript - 为什么类中的属性不是只读的(Typescript)

转载 作者:行者123 更新时间:2023-12-03 08:17:56 25 4
gpt4 key购买 nike

为什么类 PeronsImpl 中的属性名称不是只读的,我们可以将其重新分配给创建的对象?

    interface Person {
readonly name: string;
}

interface Greeting extends Person {
greet(message: string): void;
}

class PersonImpl implements Greeting {
name: string;
age = 30;
constructor(n: string) {
this.name = n;
}
greet(message: string) {
console.log(message + ' ' + this.name);
}
}

let pers = new PersonImpl("maha");
console.log(`pers : ${pers.name}`);
pers.name = "maha2";
pers.greet("hello"); //hello maha2

最佳答案

这有两个部分:类属性不会从它们扩展的类或接口(interface)继承类型;和只读属性可以与可变属性相互分配。


类属性不会从它们扩展的类或接口(interface)继承类型

当你写class Foo implements Bar {...}时,编译器不使用Bar推断 Foo 中任意一个的类型的属性。它的行为就像 implements Bar不存在,推断 Foo 的所有类型的属性,然后只需检查 Bar 。例如:

interface Foo {
x: 0 | 1;
}

class Bar implements Foo {
x = 1; // error! x is inferred as number, not 0 | 1
}

这是一个错误,因为 class Bar { x = 1 }会推断 number对于 x ,并且自 number不可分配给0 | 1 ,这是一个错误。这种行为让很多人感到惊讶和不愉快,并且有很多 GitHub 问题要求这里提供更好的东西。请参阅microsoft/TypeScript#10570一个特别长期悬而未决的问题。

这意味着 name PersonImpl的属性(property)类型为string ,并且不是 readonly :

class PersonImpl implements Greeting {
name: string; // string, not readonly string
//...
}

只读属性可以与可变属性相互分配

第二个问题是类型的区别仅在于 readonly编译器认为它们的属性是相互兼容的。您可以分配 {readonly x: string}{x: string}反之亦然,没有错误。请参阅this SO answer有关原因的更多信息,或参阅 microsoft/TypeScript#13347对于要求更改此功能的请求。

这意味着编译器不会发出 PersonImpl 的错误的name属性是可变的,而 Greetingreadonly 。这些类型不被视为不兼容。


把它们放在一起,你就会发现这里的奇怪之处。您可能会高兴地假设 PersonImplname属性是 readonly ,然后当您被允许为其分配值时会感到困惑。

此处的修复是类继承类型问题的一般解决方法;为您的属性提供显式类型注释和修饰符:

class PersonImpl implements Greeting {
readonly name: string; // annotate with readonly
/* ... */
}

let pers = new PersonImpl("maha");
pers.name = "maha2"; // error

Playground link to code

关于javascript - 为什么类中的属性不是只读的(Typescript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68773547/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com