TypeScript中“声明类”和“接口”之间的区别是什么

问题描述 投票:90回答:4

在TypeScript中,创建.d.ts源声明文件时,哪个更好?为什么?

declare class Example {
    public Method(): void; 
}

要么

interface Example {
    Method(): void;
}

我可以说的差异是接口不能有静态方法,所以你必须使用一个类。两者都没有产生任何JS输出,所以也许没关系?

javascript typescript
4个回答
138
投票

interface适用于您只想描述物体的形状。对接口来说,没有代码生成 - 它们只是类型系统中的工件。您将看到类的代码生成没有区别,具体取决于它是否具有implements子句。

declare class用于描述将要在外部存在的现有类(通常是TypeScript类,但并非总是如此)(例如,您有两个.ts文件,可以编译为两个.js文件,并且两者都包含在内script在网页上标记)。如果你使用classextends继承(无论基类型是declare class还是常规的class),编译器将生成所有代码以连接原型链和转发构造函数,什么不是。

如果您尝试从应该是接口的declare class继承,那么您将遇到运行时错误,因为生成的代码将引用没有运行时表现形式的对象。

相反,如果你只是implement一个应该是declare class的接口,你将不得不自己重新实现所有成员,并且不会利用任何可能的基类重用代码,以及在运行时检查原型链的函数将拒绝您的对象,因为它实际上不是基类的实例。

为了得到真正的书呆子,如果你有一个C ++背景,你可以大致认为interfacetypedefdeclare class作为构造函数的extern声明,严格缺少此编译单元中的定义。

从纯粹的消费方面(编写命令式代码,而不是添加新类型),interfacedeclare class之间的唯一区别是你不能new一个界面。但是,如果你想在新的extend中使用implement / class这些类型中的一种,你必须在interfacedeclare class之间正确选择。只有其中一个可以工作。

两条规则将很好地为您服务:

  • 类型的名称是否与构造函数(可与new调用的东西)对齐,这些函数实际上是在运行时出现的(例如,Date是,但JQueryStatic不是)?如果不是,你肯定想要interface
  • 我是在处理来自另一个TypeScript文件的编译类,还是类似的东西?如果是,请使用declare class

17
投票

您可以实现界面:

class MyClass implements Example {
    Method() {

    }
}

declare class语法实际上是用于为不是用TypeScript编写的外部代码添加类型定义 - 因此实现是“其他地方”。


10
投票

用外行人的话说,declare用于.ts / d.ts文件,告诉编译器我们应该期望关键字我们是declaring存在于该环境中,即使它没有在当前文件中定义。这将允许我们在使用声明的对象时具有类型安全性,因为Typescript编译器现在知道某些其他组件可以提供该变量。


3
投票

TS中declareinterface的区别:

宣布:

declare class Example {
    public Method(): void; 
}

在上面的代码中,declare让TS编译器知道某个类Example被声明。这并不意味着该课程被神奇地包括在内。作为程序员,您负责在声明它时使用该类(使用declare关键字)。

接口:

interface Example {
    Method(): void;
}

interface是一个虚拟构造,只存在于打字稿中。 typescript编译器仅将其用于类型检查。当代码编译为javascript时,整个构造将被剥离。 typescript编译器使用接口来检查对象是否具有正确的结构。

例如,当我们有以下界面时:

interface test {
  foo: number,
  bar: string,
}

我们定义的具有此接口类型的对象需要与接口完全匹配:

// perfect match has all the properties with the right types, TS compiler will not complain.
  const obj1: test = {   
    foo: 5,
    bar: 'hey',
  }
© www.soinside.com 2019 - 2024. All rights reserved.