Typescript automatically get interface properties in a class

后端 未结 3 882
一生所求
一生所求 2020-11-29 12:04

Hello TypeScript experts.

I have the following code but I have to repeat the interface properties in the class otherwise I get:

Class incorrec

相关标签:
3条回答
  • 2020-11-29 12:36

    There is no built-in support for this.

    We can however use a function that returns a class as the base type of our class. This function can lie a little bit and claim it implements the interface. We could also pass in some defaults for the members if necessary.

    interface INavigation {
      Id: number;
      AppId: number;
      NavId: number;
      Name: string;
      ParentId: string;
      PageURL: string;
      Position: string;
      Active: string;
      Desktop: string;
      Tablet: string;
      Phone: string;
      RoleId: string;
      Target: string;
    }
    
    function autoImplement<T>(defaults?: Partial<T>) {
      return class {
        constructor() {
          Object.assign(this, defaults || {});
        }
      } as new () => T
    }
    
    class Navigation extends autoImplement<INavigation>() {
      constructor(navigation: any) {
        super();
        // other init here
      }
    }
    

    If we want to have a base class, things get a bit more complicated since we have to perform a bit of surgery on the base type:

    function autoImplementWithBase<TBase extends new (...args: any[]) => any>(base: TBase) {
      return function <T>(defaults?: Partial<T>): Pick<TBase, keyof TBase> & {
        new(...a: (TBase extends new (...o: infer A) => unknown ? A : [])): InstanceType<TBase> & T
      } {
        return class extends base {
          constructor(...a: any[]) {
            super(...a);
            Object.assign(this, defaults || {});
          }
        } as any
      }
    }
    
    class BaseClass {
      m() { }
      foo: string
      static staticM() { }
      static staticFoo: string
    }
    
    class Navigation extends autoImplementWithBase(BaseClass)<INavigation>() {
      constructor(navigation: any) {
        super();
        // Other init here
      }
    }
    
    Navigation.staticFoo
    Navigation.staticM
    new Navigation(null).m();
    new Navigation(null).foo;
    
    0 讨论(0)
  • 2020-11-29 12:39

    This is now possible in Typescript using class/interface merging.

    interface Foo {
        a: number;
    }
    
    interface Baz extends Foo { }
    class Baz {
        constructor() {
            console.log(this.a); // no error here
        }
    }
    

    https://github.com/Microsoft/TypeScript/issues/340#issuecomment-184964440

    0 讨论(0)
  • 2020-11-29 12:41

    Class declarations should explicitly implement interfaces.

    0 讨论(0)
提交回复
热议问题