I just want to declare a static property in typescript interface? I have not found anywhere regarding this.
interface myInterface {
static
You can merge interface with namespace using the same name:
interface myInterface { }
namespace myInterface {
Name:string;
}
But this interface is only useful to know that its have property Name
. You can not implement it.
Yes, it is possible. Here is the solution
export interface Foo {
test(): void;
}
export namespace Foo {
export function statMethod(): void {
console.log(2);
}
}
You can't define a static property on an interface in TypeScript.
Say you wanted to change the Date
object, rather than trying to add to the definitions of Date
, you could wrap it, or simply create your rich date class to do the stuff that Date
doesn't do.
class RichDate {
public static MinValue = new Date();
}
Because Date is an interface in TypeScript, you can't extend it with a class using the extends
keyword, which is a bit of a shame as this would be a good solution if date was a class.
If you want to extend the Date object to provide a MinValue
property on the prototype, you can:
interface Date {
MinValue: Date;
}
Date.prototype.MinValue = new Date(0);
Called using:
var x = new Date();
console.log(x.MinValue);
And if you want to make it available without an instance, you also can... but it is a bit fussy.
interface DateStatic extends Date {
MinValue: Date;
}
Date['MinValue'] = new Date(0);
Called using:
var x: DateStatic = <any>Date; // We aren't using an instance
console.log(x.MinValue);
You can define interface normally:
interface MyInterface {
Name:string;
}
but you can't just do
class MyClass implements MyInterface {
static Name:string; // typescript won't care about this field
Name:string; // and demand this one instead
}
To express that a class should follow this interface for its static properties you need a bit of trickery:
var MyClass: MyInterface;
MyClass = class {
static Name:string; // if the class doesn't have that field it won't compile
}
You can even keep the name of the class, TypeScript (2.0) won't mind:
var MyClass: MyInterface;
MyClass = class MyClass {
static Name:string; // if the class doesn't have that field it won't compile
}
If you want to inherit from many interfaces statically you'll have to merge them first into a new one:
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
}
Or if you don't want to name merged interface you can do:
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
}
Working example
Follow @Duncan's @Bartvds's answer, here to provide a workable way after years passed.
At this point after Typescript 1.5 released (@Jun 15 '15), your helpful interface
interface MyType {
instanceMethod();
}
interface MyTypeStatic {
new():MyType;
staticMethod();
}
can be implemented this way with the help of decorator.
/* 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() {}
}
Refer to my comment at github issue 13462.
visual result: Compile error with a hint of static method missing.
After static method implemented, hint for method missing.
Compilation passed after both static interface and normal interface fulfilled.
I found a way to do this (without decorators) for my specific use case.
The important part that checks for static members is IObjectClass
and using cls: IObjectClass<T>
in the createObject
method:
//------------------------
// 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);