typescript 如何在打字稿中实现类常量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37265275/
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 07:08:15  来源:igfitidea点击:

How to implement class constants in typescript?

typescriptclass-constants

提问by BeetleJuice

In TypeScript, the constkeyword cannot be used to declare class properties. Doing so causes the compiler to an error with "A class member cannot have the 'const' keyword."

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

I find myself in need to clearly indicate in code that a property should not be changed. I want the IDE or compiler to error if I attempt to assign a new value to the property once it has been declared. How do you guys achieve this?

我发现自己需要在代码中明确指出不应更改属性。如果在声明属性后尝试为其分配新值,我希望 IDE 或编译器出错。你们是如何做到这一点的?

I'm currently using a read-only property, but I'm new to Typescript (and JavaScript) and wonder whether there is a better way:

我目前使用的是只读属性,但我是 Typescript(和 JavaScript)的新手,想知道是否有更好的方法:

get MY_CONSTANT():number {return 10};

I'm using typescript 1.8. Suggestions?

我正在使用打字稿 1.8。建议?

PS: I'm now using typescript 2.0.3, so I've accepted David's answer

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

回答by David Sherret

TypeScript 2.0 has the readonlymodifier:

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

It's not exactly a constant because it allows assignment in the constructor, but that's most likely not a big deal.

它不完全是一个常量,因为它允许在构造函数中赋值,但这很可能没什么大不了的。

Alternative Solution

替代方案

An alternative is to use the statickeyword with readonly:

另一种方法是使用static关键字 with 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

This has the benefit of not being assignable in the constructor and only existing in one place.

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

回答by j3ff

Constants can be declare outside of classes and use within your class. Otherwise the getproperty is a nice workaround

常量可以在类之外声明并在您的类中使用。否则,该get属性是一个不错的解决方法

const MY_CONSTANT: string = "wazzup";

export class MyClass {

    public myFunction() {

        alert(MY_CONSTANT);
    }
}

回答by am0wa

You can mark properties with readonlymodifier in your declaration:

您可以readonly在声明中使用修饰符标记属性:

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

@see TypeScript Deep Dive book - Readonly

@see TypeScript Deep Dive book - Readonly

回答by Parth Ghiya

Angular 2 Provides a very nice feature called as Opaque Constants. Create a class & Define all the constants there using opaque constants.

Angular 2 提供了一个非常好的特性,称为不透明常量。创建一个类并使用不透明常量定义所有常量。

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/"    
};

Inject it in providers in app.module.ts

将其注入 app.module.ts 中的提供程序中

You will be able to use it across every components.

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

EDIT for Angular 4 :

为 Angular 4 编辑:

For Angular 4 the new concept is Injection Token & Opaque token is Deprecated in Angular 4.

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

Injection Token Adds functionalities on top of Opaque Tokens, it allows to attach type info on the token via TypeScript generics, plus Injection tokens, removes the need of adding @Inject

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

Example Code

示例代码

Angular 2 Using Opaque Tokens

Angular 2 使用不透明令牌

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 Using Injection Tokens

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!
    ]
  }
]

Injection tokens are designed logically on top of Opaque tokens & Opaque tokens are deprecated in Angular 4.

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

回答by Krishna Ganeriwal

Either use readOnly modifier with the constant one needs to declare or one might declare a constant outside the class and use it specifically only in the required class using get operator.

要么将 readOnly 修饰符与需要声明的常量一起使用,要么可以在类之外声明一个常量,并使用 get 运算符专门仅在所需的类中使用它。

回答by Willem van der Veen

For this you can use the readonlymodifier. Object properties which are readonlycan only be assigned during initialization of the object.

为此,您可以使用readonly修饰符。这是对象属性readonly只能在对象初始化时被分配。

Example in classes:

类中的示例:

class Circle {
  readonly radius: number;

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

  get area() {
    return Math.PI * this.radius * 2;
  }
}

const circle = new Circle(12);
circle.radius = 12; // Cannot assign to 'radius' because it is a read-only property.

Example in Object literals:

对象文字中的示例:

type Rectangle = {
  readonly height: number;
  readonly width: number;
};

const square: Rectangle = { height: 1, width: 2 };
square.height = 5 // Cannot assign to 'height' because it is a read-only property

It's also worth knowing that the readonlymodifier is purely a typescript construct and when the TS is compiled to JS the construct will not be present in the compiled JS. When we are modifying properties which are readonly the TS compiler will warn us about it (it is valid JS).

还值得知道的是,readonly修饰符纯粹是一个打字稿构造,当 TS 被编译为 JS 时,该构造将不会出现在已编译的 JS 中。当我们修改只读属性时,TS 编译器会警告我们(它是有效的 JS)。

回答by Janne Harju

For me none of earlier answer works. I did need to convert my static class to enum. Like this:

对我来说,早期的答案都不起作用。我确实需要将我的静态类转换为枚举。像这样:

export enum MyConstants {
  MyFirstConstant = 'MyFirstConstant',
  MySecondConstant = 'MySecondConstant'
}

Then in my component I add new property as suggested in other answers

然后在我的组件中,我按照其他答案中的建议添加了新属性

export class MyComponent {
public MY_CONTANTS = MyConstans;
constructor() { }
}

Then in my component's template I use it this way

然后在我的组件模板中,我以这种方式使用它

<div [myDirective]="MY_CONTANTS.MyFirstConstant"> </div>

EDIT: Sorry. My problem was different than OP's. I still leave this here if someelse have same problem than I.

编辑:对不起。我的问题与 OP 不同。如果有人和我有同样的问题,我仍然把它留在这里。