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

时间:2018-11-03 05:42:17

标签: typescript

你好TypeScript专家。

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

  

类错误地实现了接口

使用接口时,是否有TypeScript的简化形式而不必声明Id: 1 Code: Code 1 Items:[ 0:{ ItemSeq: 2 ItemName: ABC2 Amount: 129 } 1:{ ItemSeq: 1 ItemName: ABC1 Amount: 200 }, 1:{ ItemSeq: 3 ItemName: ABC3 Amount: 549 } ] 和类中的所有其他属性?谢谢

Id: number;

4 个答案:

答案 0 :(得分:23)

现在可以在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

答案 1 :(得分:2)

对此没有内置支持。

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

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;

答案 2 :(得分:1)

类声明应显式实现接口。

答案 3 :(得分:1)

两个答案之间的混合,以避免通过在构造函数中使用类/接口合并和 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)