2012-12-19 139 views

回答

27

您无法在TypeScript中的接口上定义静态属性。

说你想改变Date对象,而不是试图增加的Date的定义,你可以把它包起来,或简单地创建你丰富的日期类做的东西,Date没有做。

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

因为日期是打字稿的接口,你不能用类使用extends关键字,这是一个有点羞耻的扩展它,因为这将是一个很好的解决方案,如果日期是一类。

如果你想延长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); 
+1

@Rajagopal要清楚的是,您实际上可以使用'extends'关键字扩展TS中的接口。你不能用一个类扩展一个接口(为了添加一个静态属性,你需要这样做)。 – JcFx

+0

Steve - '因为Date是TypeScript中的一个接口,所以不能使用extends关键字来扩展它 - - 这是不对的,是吗? – JcFx

+1

您可以扩展接口,但不能用类扩展它,只能实现它。我没有说清楚。 – Fenton

12

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

如果您正在使用TypeScript编写该类,那么前面给出的答案当然是正确的。它可以帮助别人知道,如果你要描述一个已经在其他地方实现的对象,那么全球构造包括静态属性可以这样声明:

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

编辑:发布作为一个完整的答案[下面](http://stackoverflow.com/a/18837239/1026362) – Bartvds

+0

在这之后发布Typescript 1.5(6.15.2015),这是一个可行的方式来描述静态成员一类。 http://stackoverflow.com/a/43674389/681830 – Val

6

@邓肯的解决方案上面的静态类型作品指定new()也与接口:

interface MyType { 
    instanceMethod(); 
} 

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

其中哪一个会让我的课程实现? –

+1

此时您不能使用接口来描述静态成员,只有实例成员。所以在这个例子中,你的类将实现'MyType'(就像'Foo类实现MyType'一样)。当描述现有的JS代码时,静态接口在定义中才是真正有用的。 – Bartvds

+0

在Typescript 1.5发布(6.15.2015)之后的这一时刻,这里描述一个类的静态成员是一种可行的方法。 http://stackoverflow.com/a/43674389/681830 – Val

3

如果你正在寻找定义一个静态类(即。所有的方法/属性是静态的),你可以做这样的事情:

interface MyStaticClassInterface { 
    foo():string; 
} 

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

在这种情况下,静态的“类”实际上只是一个纯ol'-JS对象,它实现的所有方法MyStaticClassInterface

6

可以正常定义接口:

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 
} 

你甚至可以保持类的名称,打字稿(2.0)不会介意:

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

如果您wan't从多个接口继承静态你必须首先把它们合并成一个新问题:

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 
} 

使用相同的名称工作example

+0

我得到错误TS2322:匿名类不能分配到类型 – JoshuaDavid

+0

@FireCoding您正在使用哪种TypeScript版本?我的例子使用2.0 –

0

您可以merge interface with namespace

interface myInterface { } 

namespace myInterface { 
    Name:string; 
} 

不过这个接口是只有知道它有财产Name有用。你不能实现它。

20

按照@ Duncan's @ Bartvds的回答,这里提供了一个可行的方式,经过多年过去。

在打字稿1.5后这点释放(@Jun 15 '15),您有帮助的接口

interface MyType { 
    instanceMethod(); 
} 

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

可以实现这种方式与装饰的帮助。

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

@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 open issue 13462

可视化结果: 编译错误,提示缺少静态方法。 enter image description here

实现静态方法后,提示为方法失踪。 enter image description here

静态接口和普通接口都满足后编译通过。 enter image description here

+2

你的答案是答案。非常感谢。使用Typescript 2.4.1 –

0

对于那些希望以一个静态方法添加到内置对象,如日期,很容易

interface DateConstructor { 
    fromServerDate: any 
} 

现在Date.fromServerDate(appt.changeDate)将编译好的。

+0

“DateConstructor”来自哪里? – blockhead

1

我发现了一种方法来做到这一点(没有装饰)为我的具体用例。

,检查静态成员的重要组成部分,是在createObject方法IObjectClass和使用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); 
相关问题