打字稿中的最终关键字?

时间:2015-02-14 08:19:59

标签: typescript final

有没有办法让变量可以只分配一次?喜欢这个

interface IFACE{
 a: number;
 final b: number;
}

IFACEConstructor (a: number): IFACE {
 return {a: a, b: 1}
}

test = IFACEConstructor(2);
test.a = 5 //OK
test.b = 2 //Error

4 个答案:

答案 0 :(得分:21)

自1.4起可用,您可以查看Announcing TypeScript 1.4 article, "Let/Const" support section

“除了'var'之外,TypeScript现在支持使用'let'和'const'。这些当前需要ES6输出模式,但是我们正在考虑在将来的版本中放宽这个限制。”

Const应该根据article实现。

您可以获得TypeScript 1.4 here

更新1

当然,“const与final不一样”。问题是“有没有办法让变量可以只分配一次?”。 所以,根据documentation

  

Const声明必须具有初始值设定项,除非在环境上下文中

     

写入Const

是错误的
const c = 0;
console.log(c); // OK: 0

c = 2; // Error
c++; // Error

{
    const c2 = 0;
    var c2 = 0; // not a redeclaration, as the var is hoisted out, but still a write to c2
}

而且,就目前而言(2015年11月)“const”在我看来是开箱即用的唯一途径,可以完成上述任务。

对于那些被贬低的人 - 如果你有另一个答案,请在这个帖子中与社区分享。

更新2:readonly

在Typescript 2.0中引入了readonly修饰符(感谢@basarat)。 您可以初始化 它们在声明点或构造函数中。

  

您甚至可以将类属性声明为readonly。你可以初始化   它们在声明点或构造函数中如下所示:

class Foo {
    readonly bar = 1; // OK
    readonly baz: string;
    constructor() {
        this.baz = "hello";  // OK
    }
}

但正如this thread中的@RReverser所说:

  

和往常一样,你需要使用npm i   typescript @ next获取具有实验性功能的最新编译器   包括在内。

答案 1 :(得分:3)

您可以使用set / get来实现结果。

class Test {

    constructor(public a: number, private _b: number) {}

    get b(): number {
        return this._b;
    }

}

var test = new Test(2, 1);

test.a = 5 //OK
test.b = 2 //Error

test.b无法设置,因为它没有设置器。

TS编译器不会向您发出警告,但浏览器会抛出错误。

答案 2 :(得分:2)

没有final关键字,但您可以通过以下方式使用readonly:

分配一次

class IFACE {
    constructor(public a: number, readonly b: number) {}
}

let test: IFACE = new IFACE(1, 34);

 test.a = 5; // OK
// test.b = 2; // Error

console.log(test.a, test.b); // 5 34

禁用覆盖

class IFACE {
    constructor(public a: number, readonly b: number) {
        // console.log(`b is ${this.b}`);
        this.b = 2; // b is always 2
        // console.log(`b is ${this.b}`);
    }
}

let test: IFACE = new IFACE(1, 34);

test.a = 5;
console.log(test.a, test.b); // 5 2

当你分配给一个只读字段两次时,不确定最后一个是否是一个错误 - 一次在构造函数参数中,一次在构造函数体中。

请注意,如果双重任务困扰你,那么你可以将最后一个更改为

class IFACE {
    a: number;
    readonly b: number = 2;

    constructor(a: number) { this.a = a; }
}

答案 3 :(得分:2)

您可以使用方法装饰器,并将描述符对象的writable属性设置为false。

function final(target: Object, key: string | symbol, descriptor: PropertyDescriptor) {
  descriptor.writable = false;
}

然后在包含最终方法的父类中使用装饰器。

class Parent {
  @final
  speak() {
    console.log('Parent speaking');
  }
}

如果现在扩展Parent类并尝试覆盖它的speak方法,则会出现错误:

错误:“说”是只读的

class Child extends Parent {
  // Error: "speak" is read-only
  speak() {
    console.log('Child speaking');
  }
}

通过使用装饰器,您可以非常描述性地将方法标记为最终方法。

Working example

编辑:正如Mark所指出的那样,这仅在移植到ES5或更早版本时才有效。