在这种情况下,为什么界面不能保护我?

时间:2016-11-03 23:21:20

标签: typescript

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似乎没有保护我免于修改。我用错了吗?

更新

https://github.com/Microsoft/TypeScript/issues/11578

3 个答案:

答案 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

此时您必须定义可以分配给基接口类型的类型。

enter image description here

至于只读。它按预期工作:

enter image description here

你必须明白打字稿和其他OO语言如C#之间存在一些差异。即,将一个类型变量分配给另一个是关于右侧类型是否与左侧类型相交。即

let x: X = { a: "hello", f: (x) => { } };

完全有效。

答案 2 :(得分:0)

我认为您的课程还应指定readonly关键字和类型:

class X implements IA {
    readonly a: string;