我只是想在typescript接口中声明一个静态属性?我没有找到任何关于这方面的资料。
interface myInterface {
static Name:string;
}
这可能吗?
我只是想在typescript接口中声明一个静态属性?我没有找到任何关于这方面的资料。
interface myInterface {
static Name:string;
}
这可能吗?
当前回答
解决方案
返回I的实例类型,并确保C扩展I:
type StaticImplements<I extends new (...args: any[]) => any, C extends I> = InstanceType<I>;
实例方法接口:
interface MyInstance {
instanceMethod();
}
接口采用静态方法:
interface MyClassStatic {
new (...args: any[]): MyInstance;
staticMethod();
}
类需要静态方法并使用自己的方法进行扩展:
class MyClass implements StaticImplements<MyClassStatic, typeof MyClass> {
static staticMethod();
static ownStaticMethod();
instanceMethod();
ownInstanceMethod();
}
推理
在接口中定义静态方法将在#33892中讨论,抽象静态方法将在#34516中讨论。
基于Val和Aleksey的回答(谢谢),这个解决方案:
不需要额外的运行时值 保留类自身的成员信息 允许构造函数约束
Test
原样-游乐场连结:
MyClass.staticMethod(); // OK
MyClass.ownStaticMethod(); // OK
new MyClass().instanceMethod(); // OK
new MyClass().ownInstanceMethod(); // OK
如果从MyClass - Playground中删除staticMethod:
class MyClass implements StaticImplements<MyClassStatic, typeof MyClass> {} // Type 'typeof MyClass' does not satisfy the constraint 'MyClassStatic'. Property 'staticMethod' is missing in type 'typeof MyClass' but required in type 'MyClassStatic'.
如果从MyClass - Playground中删除instanceMethod:
class MyClass implements StaticImplements<MyClassStatic, typeof MyClass> {} // Class 'MyClass' incorrectly implements interface 'MyInstance'. Property 'instanceMethod' is missing in type 'MyClass' but required in type 'MyInstance'.
其他回答
静态修饰符不能出现在类型成员上(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());
静态属性通常放在对象的(全局)构造函数上,而“interface”关键字适用于对象的实例。
如果你用TypeScript编写类,前面给出的答案当然是正确的。如果你描述的是一个已经在其他地方实现的对象,那么包含静态属性的全局构造函数可以这样声明:
declare var myInterface : {
new(): Interface;
Name:string;
}
我为我的特定用例找到了这样做的方法(不需要装饰器)。
检查静态成员的重要部分是IObjectClass,并在createObject方法中使用cls: IObjectClass<T>:
//------------------------
// 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 = (<any>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);
如果您正在寻找定义一个静态类(即。所有的方法/属性都是静态的),你可以这样做:
interface MyStaticClassInterface {
foo():string;
}
var myStaticClass:MyStaticClassInterface = {
foo() {
return 'bar';
}
};
在这种情况下,静态“类”实际上只是一个普通的-ol'-js-object,它实现了MyStaticClassInterface的所有方法
你可以正常定义接口:
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
}
工作示例