如何在 TypeScript 接口中定义静态属性

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

How to define static property in TypeScript interface

typescript

提问by Rajagopal ?

I just want to declare a static property in typescriptinterface? I have not found anywhere regarding this.

我只想在打字稿界面中声明一个静态属性?我没有找到任何关于此的地方。

interface myInterface {
  static Name:string;
}

Is it possible?

是否可以?

采纳答案by Fenton

You can't define a static property on an interface in TypeScript.

您不能在 TypeScript 的接口上定义静态属性。

Say you wanted to change the Dateobject, rather than trying to add to the definitions of Date, you could wrap it, or simply create your rich date class to do the stuff that Datedoesn't do.

假设您想更改Date对象,而不是尝试添加到 的定义Date,您可以包装它,或者简单地创建您的富日期类来完成不做的事情Date

class RichDate {
    public static MinValue = new Date();
}

Because Date is an interface in TypeScript, you can't extend it with a class using the extendskeyword, which is a bit of a shame as this would be a good solution if date was a class.

因为 Date 是 TypeScript 中的一个接口,所以你不能用extends关键字来扩展它,这有点遗憾,因为如果 date 是一个类,这将是一个很好的解决方案。

If you want to extend the Date object to provide a MinValueproperty on the prototype, you can:

如果您想扩展 Date 对象以MinValue在原型上提供属性,您可以:

interface Date {
    MinValue: Date;
}

Date.prototype.MinValue = new Date(0);

Called using:

调用使用:

var x = new Date();
console.log(x.MinValue);

And if you want to make it available without an instance, you also can... but it is a bit fussy.

如果你想让它在没有实例的情况下可用,你也可以......但它有点挑剔。

interface DateStatic extends Date {
    MinValue: Date;
}

Date['MinValue'] = new Date(0);

Called using:

调用使用:

var x: DateStatic = <any>Date; // We aren't using an instance
console.log(x.MinValue);

回答by Val

Follow @Duncan's @Bartvds's answer, here to provide a workable way after years passed.

按照@Duncan 的@Bartvds 的回答,在这里提供多年后可行的方法。

At this point after Typescript 1.5 released (@Jun 15 '15), your helpful interface

此时,在 Typescript 1.5 发布后(@Jun 15 '15),您的有用界面

interface MyType {
    instanceMethod();
}

interface MyTypeStatic {
    new():MyType;
    staticMethod();
}

can be implemented this way with the help of decorator.

可以在装饰器的帮助下以这种方式实现。

/* class decorator */
function staticImplements<T>() {
    return <U extends T>(constructor: U) => {constructor};
}

@staticImplements<MyTypeStatic>()   /* this statement implements both normal interface & static interface */
class MyTypeClass { /* implements MyType { */ /* so this become optional not required */
    public static staticMethod() {}
    instanceMethod() {}
}

Refer to my comment at github open issue 13462.

请参阅我在 github open issue 13462 上的评论。

visual result: Compile error with a hint of static method missing. enter image description here

视觉结果:编译错误,缺少静态方法的提示。 在此处输入图片说明

After static method implemented, hint for method missing. enter image description here

静态方法实现后,提示方法缺失。 在此处输入图片说明

Compilation passed after both static interface and normal interface fulfilled. enter image description here

静态接口和普通接口都完成后编译通过。 在此处输入图片说明

回答by duncan

Static properties are usually placed on the (global) constructor for the object, whereas the "interface" keyword applies to instances of the object.

静态属性通常放置在对象的(全局)构造函数上,而“interface”关键字适用于对象的实例。

The previous answer given is of course correct if you are writing the class in TypeScript. It may help others to know that if you are describing an object that is already implemented elsewhere, then the global constructor including static properties can be declared like this:

如果您使用 TypeScript 编写类,则前面给出的答案当然是正确的。其他人可能会知道,如果您正在描述一个已经在其他地方实现的对象,那么可以像这样声明包含静态属性的全局构造函数:

declare var myInterface : {
  new(): Interface;
  Name:string;
}

回答by Kamil Szot

You can define interface normally:

您可以正常定义接口:

interface MyInterface {
    Name:string;
}

but you can't just do

但你不能只做

class MyClass implements MyInterface {
    static Name:string; // typescript won't care about this field
    Name:string;         // and demand this one instead
}

To express that a class should follow this interface for its static properties you need a bit of trickery:

要表达一个类应该为其静态属性遵循此接口,您需要一些技巧:

var MyClass: MyInterface;
MyClass = class {
    static Name:string; // if the class doesn't have that field it won't compile
}

You can even keep the name of the class, TypeScript (2.0) won't mind:

你甚至可以保留类的名称,TypeScript (2.0) 不会介意:

var MyClass: MyInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that field it won't compile
}

If you wan't to inherit from many interfaces statically you'll have to merge them first into a new one:

如果您不想静态继承许多接口,则必须先将它们合并到一个新接口中:

interface NameInterface {
    Name:string;
}
interface AddressInterface {
    Address:string;
}
interface NameAndAddressInterface extends NameInterface, AddressInterface { }
var MyClass: NameAndAddressInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that static field code won't compile
    static Address:string; // if the class doesn't have that static field code won't compile
}

Or if you don't want to name merged interface you can do:

或者,如果您不想命名合并的接口,您可以执行以下操作:

interface NameInterface {
    Name:string;
}
interface AddressInterface {
    Address:string;
}
var MyClass: NameInterface & AddressInterface;
MyClass = class MyClass {
    static Name:string; // if the class doesn't have that static field code won't compile
    static Address:string; // if the class doesn't have that static field code won't compile
}

Working example

工作示例

回答by Bartvds

@duncan's solution above specifying new()for the static type works also with interfaces:

@duncan 上面new()为静态类型指定的解决方案也适用于接口:

interface MyType {
    instanceMethod();
}

interface MyTypeStatic {
    new():MyType;
    staticMethod();
}

回答by Benny Neugebauer

Static modifiers cannot appear on a type member (TypeScript error TS1070). That's why I recommend to use an abstract class to solve the mission:

静态修饰符不能出现在类型成员上(TypeScript 错误 TS1070)。这就是为什么我建议使用抽象类来解决任务:

Example

例子

// Interface definition
abstract class MyInterface {
  static MyName: string;
  abstract getText(): string;
}

// Interface implementation
class MyClass extends MyInterface {
  static MyName = 'TestName';
  getText(): string {
    return `This is my name static name "${MyClass.MyName}".`;
  }
}

// Test run
const test: MyInterface = new MyClass();
console.log(test.getText());

回答by Pavel_K

Yes, it is possible. Here is the solution

对的,这是可能的。这是解决方案

export interface Foo {

    test(): void;
}

export namespace Foo {

    export function statMethod(): void {
        console.log(2);
    }

}

回答by edan

If you're looking to define a static class (ie. all methods/properties are static), you can do something like this:

如果您想定义一个静态类(即所有方法/属性都是静态的),您可以执行以下操作:

interface MyStaticClassInterface {
  foo():string;
}

var myStaticClass:MyStaticClassInterface = {
  foo() {
    return 'bar';
  }
};

In this case, the static "class" is really just a plain-ol'-js-object, which implements all the methods of MyStaticClassInterface

在这种情况下,静态“类”实际上只是一个普通的 ol'-js 对象,它实现了 MyStaticClassInterface

回答by Aleksey L.

Another option not mentioned here is defining variable with a type representing static interface and assigning to it class expression:

此处未提及的另一个选项是使用表示静态接口的类型定义变量并为其分配类表达式:

interface MyType {
    instanceMethod(): void;
}

interface MyTypeStatic {
    new(): MyType;
    staticMethod(): void;
}

// ok
const MyTypeClass: MyTypeStatic = class MyTypeClass {
    public static staticMethod() { }
    instanceMethod() { }
}

// error: 'instanceMethod' is missing
const MyTypeClass1: MyTypeStatic = class MyTypeClass {
    public static staticMethod() { }
}

// error: 'staticMethod' is missing
const MyTypeClass2: MyTypeStatic = class MyTypeClass {
    instanceMethod() { }
}

The effect is same as in answer with decorators, but without overhead of decorators

效果与装饰器的回答相同,但没有装饰器的开销

Playground

操场

Relevant suggestion/discussionon GitHub

GitHub上的相关建议/讨论

回答by ktretyak

You can merge interface with namespaceusing the same name:

您可以使用相同的名称将接口与命名空间合并

interface myInterface { }

namespace myInterface {
  Name:string;
}

But this interface is only useful to know that its have property Name. You can not implement it.

但是这个接口只有在知道它有属性时才有用Name。你不能实施它。