为什么在 TypeScript 中实现接口时需要重新定义属性?

Thi*_*mma 9 class implements typescript

我正在研究类和接口。我有一件事情让我很恼火,这是我第一次处理这类事情,所以请耐心等待。

假设我有这个界面:

// IFoo.d.ts
export default interface IFoo {
  foo: string;
  bar: number;
}
Run Code Online (Sandbox Code Playgroud)

当我在课堂上实现它时,我会执行以下操作:

// FooModel.ts
import IFoo from './IFoo';

export default class FooModel implements IFoo {
  foo: string;
  bar: number;

  constructor({ foo, bar }: IFoo = { foo: 'hello', bar: 1 }) {
    this.foo = foo;
  }
}
Run Code Online (Sandbox Code Playgroud)

为什么我必须再次实现相同的属性?

这与复制粘贴基本相同,但有严格的约定。另外,我必须分别键入foo6bar次,才能根据接口正确分配默认可选值。

还有更有效的方法来做到这一点吗?

编辑; 我正在努力实现以下目标:

具有属性的类,其中的属性可用于打字稿的检查,如下所示: 接口

export default interface FooDTO {
  foo: string;
  bar: number;
}
Run Code Online (Sandbox Code Playgroud)

模型

export interface IFoo {
  foo: string;
  bar: number;
}

export default class FooModel implements IFoo {
  foo: string;
  bar: number;

  constructor({ foo, bar }: IFoo = { foo: 'hello', bar: 1 }) {
    this.foo = foo;
  }
}
Run Code Online (Sandbox Code Playgroud)

控制器

export default class FooController {
   public static async readAll(): Array<FooDTO> {
      // some model stuff which maps query to dto
      return Array<FooDTO>result;
   }
}
Run Code Online (Sandbox Code Playgroud)

jca*_*alz 5

我认为“为什么我必须再次实现相同的属性”的规范答案位于(越来越过时的)TypeScript 规范中:

\n\n
\n

请注意,由于 TypeScript 具有结构类型系统,因此类不需要显式声明它实现接口\xe2\x80\x94,类只需包含适当的实例成员集就足够了。类的子句implements提供了一种机制来断言和验证该类是否包含适当的实例成员集,但除此之外它对类类型没有影响

\n
\n\n

我在上面添加了强调:该implements子句根本不影响类类型;它不会向其中添加成员或更改成员的类型。它所做的只是告诉编译器在类不符合接口时发出警告。

\n\n
\n\n

您可能对 GitHub 问题microsoft/TypeScript#22815感兴趣,该问题建议将已实现接口的成员复制到实现类中。(该问题的标题是关于抽象类的,但随后的讨论并不限于此。)看起来症结在于如何处理可选成员(请参阅TS 团队负责人的评论)。该问题是一个较旧的问题,但它仍然以“需求建议”标签打开,因此,如果您非常关心它,您可能会想去那里,给它一个 ,甚至可能提供有关该问题的更多详细信息行为应该是在边缘情况下,这样就不会成为重大变化。

\n\n

在该问题中,建议使用接口合并告诉编译器类实例接口继承属性的解决方法:

\n\n
interface FooModel extends IFoo { } // merge into FooModel\nclass FooModel {\n    constructor({ foo, bar }: IFoo = { foo: \'hello\', bar: 1 }) {\n        this.foo = foo;\n        this.bar = bar;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这不是多余的,但可能比仅仅从接口重新声明属性更令人困惑。

\n\n
\n\n

无论如何,希望有帮助;祝你好运!

\n\n

Playground 代码链接

\n