Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define static property in TypeScript interface

Tags:

typescript

People also ask

How do you define a static property in TypeScript?

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.

How do I create a static variable in TypeScript?

var Circle = /** @class */ (function () { function Circle() { } Circle. pi = 3.14; return Circle; }()); The following example defines a class with static property and method and how to access it. The above Circle class includes a static property and a static method.

CAN interface have static property?

A private static field can be set from somewhere inside the interface. But a static method cannot be implemented from outside the interface since it is part of the interface itself.

Does TypeScript have static methods?

TypeScript allows us to encapsulate our static methods with access modifiers, just like regular methods.


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. enter image description here

After static method implemented, hint for method missing. enter image description here

Compilation passed after both static interface and normal interface fulfilled. enter image description here


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);

Static modifiers cannot appear on a type member (TypeScript error TS1070). That's why I recommend to use an abstract class to solve the mission:

Example

// 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());

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


Static properties are usually placed on the (global) constructor for the object, whereas the "interface" keyword applies to instances of the object.

The previous answer given is of course correct if you are writing the class in TypeScript. It may help others to know that if you are describing an object that is already implemented elsewhere, then the global constructor including static properties can be declared like this:

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

@duncan's solution above specifying new() for the static type works also with interfaces:

interface MyType {
    instanceMethod();
}

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