在TypeScript中,不能使用const关键字来声明类属性。这样做会导致编译器报错“类成员不能有'const'关键字”。

我发现自己需要在代码中明确指出不应该更改某个属性。我希望IDE或编译器在声明属性后,如果我试图将新值赋给属性时出错。你们是怎么做到的?

我目前正在使用只读属性,但我想知道是否有更好的方法:

get MY_CONSTANT():number {return 10};

我使用的是typescript 1.8。建议吗?

PS:我现在使用的是typescript 2.0.3,所以我接受了David的答案


当前回答

TypeScript 2.0有readonly修饰符:

class MyClass {
    readonly myReadOnlyProperty = 1;

    myMethod() {
        console.log(this.myReadOnlyProperty);
        this.myReadOnlyProperty = 5; // error, readonly
    }
}

new MyClass().myReadOnlyProperty = 5; // error, readonly

它不是一个确切的常数,因为它允许在构造函数中赋值,但这很可能不是一个大问题。

可选择的解决方案

另一种方法是使用static关键字和readonly:

class MyClass {
    static readonly myReadOnlyProperty = 1;

    constructor() {
        MyClass.myReadOnlyProperty = 5; // error, readonly
    }

    myMethod() {
        console.log(MyClass.myReadOnlyProperty);
        MyClass.myReadOnlyProperty = 5; // error, readonly
    }
}

MyClass.myReadOnlyProperty = 5; // error, readonly

这样做的好处是不能在构造函数中赋值,只存在于一个地方。

其他回答

你可以在你的声明中用只读修饰符标记属性:

export class MyClass {
  public static readonly MY_PUBLIC_CONSTANT = 10;
  private static readonly myPrivateConstant = 5;
}

@see TypeScript Deep Dive book - Readonly

Angular 2提供了一个非常好的特性,叫做Opaque Constants。 创建一个类并使用不透明常量定义其中的所有常量。

import { OpaqueToken } from "@angular/core";

export let APP_CONFIG = new OpaqueToken("my.config");

export interface MyAppConfig {
    apiEndpoint: string;
}

export const AppConfig: MyAppConfig = {    
    apiEndpoint: "http://localhost:8080/api/"    
};

将它注入到提供商中 app.module.ts

您将能够跨每个组件使用它。

Angular 4的编辑:

对于Angular 4,新概念是注入令牌&不透明令牌在Angular 4中已弃用。

注入令牌在不透明令牌的基础上增加了功能,它允许通过TypeScript泛型在令牌上附加类型信息,加上注入令牌,不需要添加@Inject

示例代码

使用不透明令牌

const API_URL = new OpaqueToken('apiUrl'); //no Type Check


providers: [
  {
    provide: DataService,
    useFactory: (http, apiUrl) => {
      // create data service
    },
    deps: [
      Http,
      new Inject(API_URL) //notice the new Inject
    ]
  }
]

Angular 4使用注入令牌

const API_URL = new InjectionToken<string>('apiUrl'); // generic defines return value of injector


providers: [
  {
    provide: DataService,
    useFactory: (http, apiUrl) => {
      // create data service
    },
    deps: [
      Http,
      API_URL // no `new Inject()` needed!
    ]
  }
]

注入令牌在逻辑上是在Opaque令牌之上设计的,而Opaque令牌在Angular 4中已弃用。

要么将readOnly修饰符与需要声明的常量一起使用,要么在类外声明一个常量,然后使用get操作符专门在所需的类中使用它。

你也可以简单地声明比如:src/classes/Car/consts/Honda.ts

export const CIVIC: string = "Civic";

export default {
    CIVIC: CIVIC
};

然后在类文件中执行如下操作:

import Honda from "./consts/Honda";

export class Car {

    protected model: string = Honda.Civic;

    [...]

}

export default Car;

这样,你就能确保它是一个常数。如果您正在构建数据集,这种方法也非常有用。

TypeScript 2.0有readonly修饰符:

class MyClass {
    readonly myReadOnlyProperty = 1;

    myMethod() {
        console.log(this.myReadOnlyProperty);
        this.myReadOnlyProperty = 5; // error, readonly
    }
}

new MyClass().myReadOnlyProperty = 5; // error, readonly

它不是一个确切的常数,因为它允许在构造函数中赋值,但这很可能不是一个大问题。

可选择的解决方案

另一种方法是使用static关键字和readonly:

class MyClass {
    static readonly myReadOnlyProperty = 1;

    constructor() {
        MyClass.myReadOnlyProperty = 5; // error, readonly
    }

    myMethod() {
        console.log(MyClass.myReadOnlyProperty);
        MyClass.myReadOnlyProperty = 5; // error, readonly
    }
}

MyClass.myReadOnlyProperty = 5; // error, readonly

这样做的好处是不能在构造函数中赋值,只存在于一个地方。