我只是想在typescript接口中声明一个静态属性?我没有找到任何关于这方面的资料。
interface myInterface {
static Name:string;
}
这可能吗?
我只是想在typescript接口中声明一个静态属性?我没有找到任何关于这方面的资料。
interface myInterface {
static Name:string;
}
这可能吗?
当前回答
虽然静态关键字不支持接口在Typescript 但我们可以通过创建一个具有静态成员的函数接口来实现。
在下面的代码中,我创建了一个函数接口Factory,它有两个静态成员serialNumber和printSerial。
// 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();
其他回答
我执行了一个类似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)
我最终失去了一个比我想通过类的静态部分的接口实现的更重要的类型。
瓦尔使用装饰器的解决方案避免了这个陷阱。
静态修饰符不能出现在类型成员上(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());
温特特拉特给出了一个很好的答案,让我走上了正确的轨道。 然而,强制在静态接口中包含构造函数是非常不方便的。
简化版本
反转extends函数得到:
type Static<TClass extends IStaticInterface & { new(...args) }, IStaticInterface>
= InstanceType<TClass>;
不需要为接口添加构造函数:
interface IMeow { readonly IsMeow: boolean; }
并像这样方便地使用:
class Cat implements Static<typeof Cat, IMeow> {
readonly static IsMeow = true;
}
就像之前一样,如果Cat中缺少静态的IsMeow,它会给出一个非常明确的错误。 也像以前一样,它在其他方面仍然正常工作。
奇特的可读性(主观)
在类型后面需要一个"implements"字符串:
type Static<TClass extends IStaticInterface & { new(...args) },
_txt extends "implements", IStaticInterface>
= InstanceType<TClass>;
这里再次演示我们的猫:
class Cat implements Static<typeof Cat, "implements", IMeow> {
static readonly IsMeow = true;
}
合并多个(过多)
这真的不需要,你只需要重复Static<…>,但下面是:
type Static<TClass extends InterfacesCombined & { new(...args) }, _txt extends "implements",
IStaticInterface, IStatic2 = {}, IStatic3 = {}, IStatic4 = {}, IStatic5 = {},
InterfacesCombined extends IStaticInterface & IStatic2 & IStatic3 & IStatic4 & IStatic5
= IStaticInterface & IStatic2 & IStatic3 & IStatic4 & IStatic5>
= InstanceType<TClass>;
为了演示让我们升级我们的猫更复杂:
interface IPurr { purr(): string; }
interface ILick { Lick(human: any): void; }
用法如下:
class Cat implements IPurr, Static<typeof Cat, "implements", IMeow, ILick> {
static readonly IsMeow = true;
static Lick(human: any) { /* obey me homan! */ }
purr() { return "Prrrrr"; }
}
一个具体的静态接口
如果你经常使用静态接口,你不会想要键入所有的静态<…的东西。 首先让我们先把这个小帮手弄走:
type New<T> = { new(...args: any): T };
现在让我们“烘焙”一个静态的ILick接口:
type IStaticLick<TClass extends ILick & New<InstanceType<TClass>> = InstanceType<TClass>;
瞧:
class Cat2 implements IStaticLick<typeof Cat2> {
static Lick(human: any) { /* obey me homan! */ }
}
到底发生了什么?
我们只是要求typeof T实现一些东西,使其成为“静态接口”的有效参数。
所以如果接口IFoo {stuff} +类Foo实现IFoo说Foo是“stuff”,那么我们所说的是“stuff”必须在T中,因为T被允许在Static<T中,…>。
所以类Foo的implements部分实现了Static<…>并没有真正说明Foo有什么特殊的东西。更确切地说,我们只是说我们有这些花哨的<括号>,里面是一个只接受“东西”滚轮的VIP俱乐部!
换句话说,我们可以写成:
class FakeCat implements IStaticLick<typeof Cat2> { }
...明白我的意思了吧?
我们试图通过要求静态<TClass,…来减少这个明显的问题。>实际实现TClass的实例类型。但是,如果InstanceType<TClass>没有任何实例成员(例如我们的Cat2类),则此方法将不起任何作用。
FakeCat确实实现了Cat2 -因为它不是很难实现:{}。
Demo
操场上的链接
静态属性通常放在对象的(全局)构造函数上,而“interface”关键字适用于对象的实例。
如果你用TypeScript编写类,前面给出的答案当然是正确的。如果你描述的是一个已经在其他地方实现的对象,那么包含静态属性的全局构造函数可以这样声明:
declare var myInterface : {
new(): Interface;
Name:string;
}
如果您正在寻找定义一个静态类(即。所有的方法/属性都是静态的),你可以这样做:
interface MyStaticClassInterface {
foo():string;
}
var myStaticClass:MyStaticClassInterface = {
foo() {
return 'bar';
}
};
在这种情况下,静态“类”实际上只是一个普通的-ol'-js-object,它实现了MyStaticClassInterface的所有方法