代码之家  ›  专栏  ›  技术社区  ›  danday74

Typescript自动获取类中的接口属性

  •  0
  • danday74  · 技术社区  · 6 年前

    你好打字专家。

    我有以下代码,但我必须在类中重复接口属性,否则我会得到:

    类错误地实现了接口

    Id: number; 其他的属性呢?谢谢

    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;
    }
    
    class Navigation implements 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;
    
      constructor(navigation: any) {
        this.Id = navigation.Id
        this.AppId = navigation.NavAppId
        this.NavId = navigation.NavId
        this.Name = navigation.NavName
        this.ParentId = navigation.NavParentId
        this.PageURL = navigation.NavPageURL
        this.Position = navigation.NavPosition
        this.Active = navigation.NavActive
        this.Desktop = navigation.NavDesktop
        this.Tablet = navigation.NavTablet
        this.Phone = navigation.NavPhone
        this.RoleId = navigation.NavRoleId
        this.Target = navigation.NavTarget
      }
    }
    
    2 回复  |  直到 6 年前
        1
  •  30
  •   SamB    5 年前

    这在Typescript中现在可以使用类/接口合并。

    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

        2
  •  13
  •   Titian Cernicova-Dragomir    6 年前

    但是,我们可以使用返回类的函数作为类的基类型。这个函数可以稍微撒谎,并声称它实现了接口。如果有必要,我们还可以为成员传递一些默认值。

    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
      }
    }
    

    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;
    
        3
  •  1
  •   Quentin Gary    3 年前

    这两个答案之间的混合,通过在构造函数中使用类/接口合并和Object.assign来避免构造函数中的长赋值:

    interface Foo {
        a: number;
        b: number;
    }
    
    interface Baz extends Foo { }
    
    class Baz  {
        c: number = 4
    
      constructor (foo: Foo) {
        Object.assign(this, foo, {})
      }
      
      getC() {
        return this.c
      }
    }
    
    let foo: Foo = {
        a: 3,
        b: 8
    }
    
    let baz = new Baz(foo)
    // keep methods and properties
    console.warn(baz)
    
        4
  •  0
  •   samira mokaram    6 年前

    类声明应该显式实现接口。