我只是想在typescript接口中声明一个静态属性?我没有找到任何关于这方面的资料。

interface myInterface {
  static Name:string;
}

这可能吗?


当前回答

你可以正常定义接口:

interface MyInterface {
    Name:string;
}

但你不能这么做

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

为了表示一个类应该遵循这个接口来获取它的静态属性,你需要一点技巧:

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

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

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

如果你想静态地继承许多接口,你必须首先将它们合并到一个新的接口中:

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
}

或者如果你不想命名合并接口,你可以这样做:

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
}

工作示例

其他回答

在TypeScript中,你不能在接口上定义静态属性。

假设您想要更改Date对象,而不是尝试添加到Date的定义中,您可以包装它,或者简单地创建富Date类来完成Date没有完成的工作。

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

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

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

interface Date {
    MinValue: Date;
}

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

使用:

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

如果你想让它在没有实例的情况下可用,你也可以…但这有点繁琐。

interface DateStatic extends Date {
    MinValue: Date;
}

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

使用:

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

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

interface myInterface { }

namespace myInterface {
  Name:string;
}

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

你可以正常定义接口:

interface MyInterface {
    Name:string;
}

但你不能这么做

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

为了表示一个类应该遵循这个接口来获取它的静态属性,你需要一点技巧:

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

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

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

如果你想静态地继承许多接口,你必须首先将它们合并到一个新的接口中:

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
}

或者如果你不想命名合并接口,你可以这样做:

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
}

工作示例

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

例子

// 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());

我执行了一个类似Kamil sot的解决方案,但却产生了意想不到的效果。我没有足够的声誉来发表这条评论,所以我把它贴在这里,以防有人正在尝试这个解决方案并阅读这篇文章。

解决方案是:

interface MyInterface {
    Name: string;
}

const MyClass = class {
    static Name: string;
};

但是,使用类表达式不允许我使用MyClass作为类型。如果我这样写:

const myInstance: MyClass;

myInstance的类型是any,我的编辑器显示以下错误:

'MyClass' refers to a value, but is being used as a type here. Did you mean 'typeof MyClass'?ts(2749)

我最终失去了一个比我想通过类的静态部分的接口实现的更重要的类型。

瓦尔使用装饰器的解决方案避免了这个陷阱。