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
Final keyword in typescript?
提问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.b
cannot 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 speak
method 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。
Edit:As Mark pointed out, this only works when transpiling to ES5 or earlier.
编辑:正如马克指出的那样,这仅在转换为 ES5 或更早版本时才有效。