How to define static property in TypeScript interface
我只想在Typescript接口中声明静态属性? 我没有找到关于此的任何地方。
1 2 3 | interface myInterface { static Name:string; } |
可能吗?
遵循@Duncan的@Bartvds的答案,这里提供了一种经过多年的可行方法。
在Typescript 1.5发布之后(@Jun 15 '15),这是您的有用界面
1 2 3 4 5 6 7 8 | interface MyType { instanceMethod(); } interface MyTypeStatic { new():MyType; staticMethod(); } |
可以在装饰器的帮助下以这种方式实现。
1 2 3 4 5 6 7 8 9 10 | /* 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() {} } |
请参阅我在github开放问题13462上的评论。
视觉效果:
缺少静态方法提示的编译错误。
实施静态方法后,提示缺少方法。
静态接口和普通接口都满足后,编译通过。
您无法在TypeScript中的接口上定义静态属性。
假设您要更改
1 2 3 | class RichDate { public static MinValue = new Date(); } |
因为Date是TypeScript中的接口,所以不能使用
如果要扩展Date对象以在原型上提供
1 2 3 4 5 | interface Date { MinValue: Date; } Date.prototype.MinValue = new Date(0); |
调用使用:
1 2 | var x = new Date(); console.log(x.MinValue); |
而且,如果您想在没有实例的情况下使它可用,您也可以...但是有点麻烦。
1 2 3 4 5 | interface DateStatic extends Date { MinValue: Date; } Date['MinValue'] = new Date(0); |
调用使用:
1 2 | var x: DateStatic = Date; // We aren't using an instance console.log(x.MinValue); |
您可以正常定义接口:
1 2 3 | interface MyInterface { Name:string; } |
但是你不能只是做
1 2 3 4 | class MyClass implements MyInterface { static Name:string; // typescript won't care about this field Name:string; // and demand this one instead } |
为了表示一个类应该遵循此接口的静态属性,您需要一些技巧:
1 2 3 4 | var MyClass: MyInterface; MyClass = class { static Name:string; // if the class doesn't have that field it won't compile } |
您甚至可以保留类的名称,TypeScript(2.0)不会介意:
1 2 3 4 | var MyClass: MyInterface; MyClass = class MyClass { static Name:string; // if the class doesn't have that field it won't compile } |
如果您不想从多个接口静态继承,则必须先将它们合并为一个新接口:
1 2 3 4 5 6 7 8 9 10 11 12 | 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 } |
或者,如果您不想命名合并接口,则可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 | 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 } |
工作实例
静态属性通常放置在对象的(全局)构造函数上,而" interface"关键字适用于对象的实例。
如果您使用TypeScript编写类,那么给出的先前答案当然是正确的。它可能会帮助其他人知道,如果您描述的是已在其他地方实现的对象,则可以像这样声明包含静态属性的全局构造函数:
1 2 3 4 | declare var myInterface : { new(): Interface; Name:string; } |
上面为静态类型指定
1 2 3 4 5 6 7 8 | interface MyType { instanceMethod(); } interface MyTypeStatic { new():MyType; staticMethod(); } |
如果要定义一个静态类(即所有方法/属性都是静态的),则可以执行以下操作:
1 2 3 4 5 6 7 8 9 | interface MyStaticClassInterface { foo():string; } var myStaticClass:MyStaticClassInterface = { foo() { return 'bar'; } }; |
在这种情况下,静态"类"实际上只是一个普通的ol-js对象,它实现了
静态修饰符不能出现在类型成员上(TypeScript错误TS1070)。这就是为什么我建议使用抽象类来解决任务的原因:
例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // 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()); |
我找到了一种针对我的特定用例的方法(没有装饰器)。
检查静态成员的重要部分是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | //------------------------ // Library //------------------------ interface IObject { id: number; } interface IObjectClass< T > { new(): T; table_name: string; } function createObject<T extends IObject>(cls: IObjectClass< T >, data:Partial< T >):T { let obj:T = (Object).assign({}, data, { id: 1, table_name: cls.table_name, } ) return obj; } //------------------------ // Implementation //------------------------ export class User implements IObject { static table_name: string = 'user'; id: number; name: string; } //------------------------ // Application //------------------------ let user = createObject(User, {name: 'Jimmy'}); console.log(user.name); |
您可以使用相同的名称将接口与名称空间合并:
1 2 3 4 5 | interface myInterface { } namespace myInterface { Name:string; } |
但是此接口仅在知道其具有属性
对的,这是可能的。这是解决方案
1 2 3 4 5 6 7 8 9 10 11 12 | export interface Foo { test(): void; } export namespace Foo { export function statMethod(): void { console.log(2); } } |
虽然Typescript的界面不支持static关键字
但是我们可以通过创建具有静态成员的
在下面的代码中,我创建了一个具有两个静态成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // factory is a function interface interface Factory< T > { (name: string, age: number): T; //staic property serialNumber: number; //static method printSrial: () => void; } class Dog { constructor(public name: string, public age: number) { } } const dogFactory: Factory<Dog> = (name, age) => { return new Dog(name, age); } // initialising static members dogFactory.serialNumber = 1234; dogFactory.printSrial = () => console.log(dogFactory.serialNumber); //instance of Dog that DogFactory creates const myDog = dogFactory("spike", 3); //static property that returns 1234 console.log(dogFactory.serialNumber) //static method that prints the serial 1234 dogFactory.printSrial(); |