declare class Example {
public Method(): void;
}
或者
interface Example {
Method(): void;
}
我能看出的区别是接口不能有静态方法,所以必须使用类。两者都不会产生任何JS输出,所以也许并不重要?
declare class Example {
public Method(): void;
}
或者
interface Example {
Method(): void;
}
interface
用于描述对象的形状,不会生成任何代码,仅是类型系统中的一个构件。对于类的代码生成,无论是否有implements
子句,都不会有任何差异。
declare class
用于描述一个已存在的类(通常是TypeScript类,但不总是),该类将在外部存在(例如,您有两个.ts文件编译为两个.js文件,并通过script
标签包含在网页中)。如果您使用extends
从class
继承(无论基类型是declare class
还是常规class
),编译器将生成所有代码来连接原型链和转发构造函数等。
如果您试图从应该是接口的declare class
继承,那么您会遇到运行时错误,因为生成的代码将引用一个没有运行时表现的对象。
相反,如果您只是实现了应该是declare class
的接口,那么您将不得不重新实现所有成员,并且不会利用来自潜在基类的任何代码重用,并且在运行时检查原型链的函数将拒绝将您的对象视为基类实例。
如果您有C++背景,可以粗略地将interface
视为typedef
,将declare class
视为在本编译单元中严格缺少定义的构造函数的extern
声明。
就消费方面而言(编写命令式代码,不添加新类型),interface
和 declare class
之间唯一的区别是你无法通过 new
关键字实例化一个接口。但是,如果你打算在一个新的类中 extends
/implement
这些类型中的一个,那么你绝对必须正确地选择 interface
或 declare class
中的一个,只有其中一个才能起作用。
以下两条规则将为你服务:
new
调用的东西)对齐,并且在运行时实际存在(例如,Date
存在,但 JQueryStatic
不存在)?如果答案是否定的,则你肯定需要使用 interface
declare class
new
运算符。然而,接口可以有构造签名,这意味着你可以在接口类型的值上调用 new
运算符。这与 class
的工作方式非常不同,因为构造函数签名在类型名称本身上而不是在该类型的表达式上。 - Ryan Cavanaugh你可以实现这个接口:
class MyClass implements Example {
Method() {
}
}
而declare class
语法实际上是用于为不是用TypeScript编写的外部代码添加类型定义的 - 因此,其实现是“在别处”。
通俗来讲,在.ts
/d.ts
文件中使用declare
关键字告诉编译器我们期望在该环境中存在声明的关键字,即使它在当前文件中没有定义。这将允许我们在使用声明对象时具有类型安全性,因为Typescript编译器现在知道某些其他组件可能会提供该变量。
declare
和interface
在TS中的区别:declare:
用于告诉编译器有哪些全局变量已经存在,不需要编译器再去查找或报错。
interface:
用于定义一个对象的属性和方法的类型,可以被类、函数等实现或继承。
declare class Example {
public Method(): void;
}
declare
声明了 TS 编译器在某个地方有一个名为 Example
的类。这并不意味着该类会自动包含进来。作为程序员,在声明时(使用 declare
关键字),需要确保该类可用。
接口:
interface Example {
Method(): void;
}
接口
是一个虚拟构造,仅存在于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',
}