在 TypeScript 中,创建 .d.ts 源声明文件时,哪个更可取,为什么?
declare class Example {
public Method(): void;
}
或者
interface Example {
Method(): void;
}
我能说的区别是接口不能有静态方法,所以你必须为此使用一个类。两者都不产生任何 JS 输出,所以也许这无关紧要?
在 TypeScript 中,创建 .d.ts 源声明文件时,哪个更可取,为什么?
declare class Example {
public Method(): void;
}
或者
interface Example {
Method(): void;
}
我能说的区别是接口不能有静态方法,所以你必须为此使用一个类。两者都不产生任何 JS 输出,所以也许这无关紧要?
interface
当您只想描述对象的形状时。从来没有接口的代码生成——它们只是类型系统中的一个工件。根据类是否有implements
子句,您不会看到类的代码生成有什么不同。
declare class
用于描述将在外部存在的现有类(通常是 TypeScript 类,但并非总是如此)时(例如,您有两个 .ts 文件编译为两个 .js 文件,并且都通过script
标签包含在内)在网页中)。如果您从class
using继承extends
(无论基类型是 adeclare class
还是常规类型class
),编译器将生成所有代码以连接原型链和转发构造函数以及其他什么不是。
如果您尝试从本declare class
应是接口的a 继承,则会出现运行时错误,因为生成的代码将引用没有运行时表现形式的对象。
相反,如果你只是implement
一个应该是 a 的接口declare class
,你将不得不自己重新实现所有成员,并且不会利用任何来自潜在基类和函数的代码重用在运行时检查原型链将拒绝您的对象,因为它实际上不是基类的实例。
要获得真正的书呆子,如果你有一个C ++背景,你可以大致认为interface
是typedef
和declare class
作为extern
一个构造函数的声明缺乏严格在此编译单元的定义。
从纯消费方面(编写命令式代码,不添加新类型)来看,interface
和之间的唯一区别declare class
是您不能new
成为接口。但是,如果你打算extend
/implement
这些类型在新的一个class
,你绝对得有间正确地选择interface
和declare class
。只有其中之一会起作用。
两条规则对你很有帮助:
new
运行时实际存在的构造函数(可调用的东西)对齐(例如,Date
是,但JQueryStatic
不是)?如果没有,你肯定想要interface
declare class
您可以实现接口:
class MyClass implements Example {
Method() {
}
}
而declare class
语法实际上旨在用于为不是用 TypeScript 编写的外部代码添加类型定义 - 因此实现是“其他地方”。
通俗地说,declare
在.ts
/d.ts
文件中用于告诉编译器我们应该期望我们将declaring
存在于该环境中的关键字,即使它没有在当前文件中定义。这将使我们在使用声明的对象时具有类型安全性,因为 Typescript 编译器现在知道某些其他组件可能会提供该变量。
declare
和interface
TS之间的区别:宣布:
declare class Example {
public Method(): void;
}
在上面的代码中,declare
让 TS 编译器知道在某个地方Example
声明了类。这并不意味着该类被神奇地包含在内。作为程序员,您有责任在声明类时(使用declare
关键字)使类可用。
界面:
interface Example {
Method(): void;
}
Aninterface
是一种仅存在于typescript中的虚拟结构。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',
}