typescript 打字稿中的最终关键字?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28513780/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:35:27  来源:igfitidea点击:

Final keyword in typescript?

typescriptfinal

提问by Andrei Andreev

Is there any way to make a variable available to be assigned only once? Like this

有没有办法让一个变量只能被分配一次?像这样

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

采纳答案by TSV

It will be available since 1.4, you can check the Announcing TypeScript 1.4 article, "Let/Const" support section:

它从 1.4 开始可用,您可以查看宣布 TypeScript 1.4 的文章“Let/Const”支持部分

"TypeScript now supports using ‘let' and ‘const' in addition to ‘var'. These currently require the ES6 output mode, but we're are investigating relaxing this restriction in future versions."

“除了 'var' 之外,TypeScript 现在还支持使用 'let' 和 'const'。这些目前需要 ES6 输出模式,但我们正在研究在未来的版本中放宽这一限制。”

Const should be implemented according to the article.

Const 应该按照文章来实现。

You can get TypeScript 1.4 here.

您可以在此处获取 TypeScript 1.4 。

Update 1

更新 1

Of course, "const is not the same as final". The question was "Is there any way to make a variable available to be assigned only once?". So, according this documentation:

当然,“const 与 final 不同”。问题是“有没有办法让一个变量只能分配一次?”。因此,根据此文档

Const declarations must have an initializer, unless in ambient context

It is an error to write to a Const

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
}

And, for now (Nov, 2015) "const" seems to me the only way, given by typescript out-of-the-box, to accomplish the above task.

并且,目前(2015 年 11 月)“const”在我看来是完成上述任务的唯一方法,由打字稿开箱即用。

For those, who downvoted - if you have another answer, please, share it in this thread with comunity.

对于那些投反对票的人 - 如果您有其他答案,请在此线程中与社区分享。

Update 2: readonly

更新 2:只读

The readonlymodifier (thanks to @basarat) has been introduced in Typescript 2.0. You can initialize them at the point of declaration or in the constructor.

只读修饰符(感谢@basarat)已打字稿2.0被引入。您可以在声明点或构造函数中初始化它们。

You can even declare a class property as readonly. You can initialize them at the point of declaration or in the constructor as shown below:

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

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

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

But as said @RReverser in this thread:

但正如此线程中的@RReverser 所说:

As usual with all the fresh stuff, you need to use npm i typescript@next to get the latest compiler with experimental features included.

与所有新鲜事物一样,您需要使用 npm i typescript@next 来获取包含实验性功能的最新编译器。

回答by Mihai R?ducanu

You could use set/get to achieve the result.

您可以使用 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.bcannot be set because it doesn't have a setter.

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

TS compiler will not warn you about it, but the browser will throw an error.

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

回答by smac89

There is no final keyword, but you can make use of readonly in the following ways:

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

Assign once

分配一次

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

Disable overriding

禁用覆盖

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

Not sure if the last one is a bug seeing as you are assigning to a readonly field twice - once in the constructor parameter, and once in the constructor body.

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

Note you can change the last one to this if the double assignment bothers you as much as it did me:

请注意,如果双重分配对您的困扰和我一样困扰,您可以将最后一个更改为

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

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

回答by kexplx

You could use a method decorator and set the writable property of the descriptor object to false.

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

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

Then use the decorator in the parent class that contains the final method.

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

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

If you now extend the Parent class and try to overwrite it's speakmethod you will get an error:

如果您现在扩展 Parent 类并尝试覆盖它的speak方法,您将收到一个错误:

Error: "speak" is read-only

错误:“speak”是只读的

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

By using the decorator you have a very descriptive way of marking methods as final.

通过使用装饰器,您可以通过一种非常描述性的方式将方法标记为 final。

Working example

工作示例

Edit:As Mark pointed out, this only works when transpiling to ES5 or earlier.

编辑:正如马克指出的那样,这仅在转换为 ES5 或更早版本时才有效。