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

dan*_*y74 22 typescript

你好 TypeScript 专家。

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

类错误地实现了接口

使用接口时,是否有 TypeScript 的简写来执行此操作而无需声明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
  }
}
Run Code Online (Sandbox Code Playgroud)

Sam*_*amB 32

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

interface Foo {
    a: number;
}

interface Baz extends Foo { }
class Baz {
    constructor() {
        console.log(this.a); // no error here
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 谢谢你的提示。这应该是选择的答案 (4认同)
  • 这确实将接口的所有属性添加到类中,但是如何避免构造函数中赋值的巨大混乱? (3认同)

Tit*_*mir 13

对此没有内置支持。

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

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
  }
}
Run Code Online (Sandbox Code Playgroud)

如果我们想要一个基类,事情会变得有点复杂,因为我们必须对基类进行一些手术:

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;
Run Code Online (Sandbox Code Playgroud)