interface IA {
readonly a: string;
f(x: string): void;
}
class X implements IA {
a;
f(x) {
this.a = 1;
}
}
let x = new X().a;
令人惊讶的是,此代码编译。
X.a
的类型推断为any
,为什么会这样?readonly
似乎没有保护我免于修改。我用错了吗? 答案 0 :(得分:1)
它会推断X.a
,因为您还没有指定类型
当您的类实现一个接口时,它必须指定接口所定义的所有内容,如果您不想包含该成员a
:
class X implements IA {
f(x) {
this.a = 3;
}
}
你会得到:
Class' X'错误地实现了界面' IA' 财产' a'在' X'
中缺少
和
财产' a'在' X'
类型中不存在
您不会因为不包括a
的类型而导致任何错误,因为它会自动any
并且满足编译器。
/>
您可以使用compiler options:
noImplicitAny
告诉编译器检查这一点
使用隐含的'any'类型
提高表达式和声明的错误
readonly
部分未得到强制执行,因为readonly
界面中只有IA
但不属于该类:
class X implements IA {
a;
f(x) {
(this as IA).a = ""; // Error: Left-hand side of assignment expression cannot be a constant or a read-only property
}
}
和
class X implements IA {
readonly a;
f(x) {
this.a = ""; // Error: Left-hand side of assignment expression cannot be a constant or a read-only property
}
}
答案 1 :(得分:1)
几乎任何非类型变量隐式为any
。您可以在编译器选项中禁用它:
"noImplicitAny": true
此时您必须定义可以分配给基接口类型的类型。
至于只读。它按预期工作:
你必须明白打字稿和其他OO语言如C#之间存在一些差异。即,将一个类型变量分配给另一个是关于右侧类型是否与左侧类型相交。即
let x: X = { a: "hello", f: (x) => { } };
完全有效。
答案 2 :(得分:0)
我认为您的课程还应指定readonly
关键字和类型:
class X implements IA {
readonly a: string;