How to define static property in TypeScript interface

前端 未结 14 1180
你的背包
你的背包 2020-11-28 05:49

I just want to declare a static property in typescript interface? I have not found anywhere regarding this.

interface myInterface {
  static         


        
相关标签:
14条回答
  • 2020-11-28 06:15

    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.

    0 讨论(0)
  • 2020-11-28 06:16

    Yes, it is possible. Here is the solution

    export interface Foo {
    
        test(): void;
    }
    
    export namespace Foo {
    
        export function statMethod(): void {
            console.log(2);
        }
    
    }
    
    0 讨论(0)
  • 2020-11-28 06:18

    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);
    
    0 讨论(0)
  • 2020-11-28 06:18

    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

    0 讨论(0)
  • 2020-11-28 06:21

    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.

    0 讨论(0)
  • 2020-11-28 06:21

    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);
    
    0 讨论(0)
提交回复
热议问题