“声明类”之间的区别是什么?和“界面”在TypeScript中 [英] What's the difference between "declare class" and "interface" in TypeScript

查看:105
本文介绍了“声明类”之间的区别是什么?和“界面”在TypeScript中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In TypeScript, when creating .d.ts source declaration files, which is preferable and why?

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

interface Example {
    Method(): void;
}

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

The differences that I can tell are that interfaces can't have static methods, so you must use a class for that. Both don't product any JS output, so perhaps it doesn't matter?

推荐答案

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

interface is for when you simply want to describe the shape of an object. There's no code generation, ever, for interfaces -- they're solely an artifact in the type system. You'll see no difference in the code generation for a class depending on whether or not it has an implements clause.

声明类适用于想要描述现有类(通常是TypeScript类,但并非总是如此)的外部present(例如,您有两个.ts文件,它们编译为两个.js文件,并且两者都通过网页中的 script 标记包含在内)。如果您使用 extends 继承(无论基类型是否为声明class 或一个常规的)编译器将生成所有代码以连接原型链和转发构造函数,而不是。

declare class is for when you want to describe an existing class (usually a TypeScript class, but not always) that is going to be externally present (for example, you have two .ts files that compile to two .js files and both are included via script tags in a webpage). If you inherit from a class using extends (regardless of whether the base type was a declare class or a regular class) the compiler is going to generate all the code to hook up the prototype chain and forwarding constructors and what not.

如果你尝试从一个应该是接口的声明类继承,你将会遇到运行时错误因为生成的代码将引用一个没有运行时表现形式的对象。

If you try to inherit from a declare class that should have been an interface, you are going to have a runtime error because that generated code will be referring to an object with no runtime manifestation.

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

Conversely, if you simply implement an interface that should have been a declare class, you're going to have to re-implement all the members yourself and won't be taking advantage of any code re-use from the would-be base class, and functions that check the prototype chain at runtime will reject your object as not actually being an instance of the base class.

要真正的书呆子,如果你有一个C ++ bac kground,你可以大致认为接口 typedef 声明类作为 extern 的构造函数声明,它严格缺少此编译单元中的定义。

To get really nerdy, if you have a C++ background, you can roughly think of interface as typedef and declare class as an extern declaration of a constructor that strictly lacks a definition in this compile unit.

来自纯粹的消费方(编写命令式代码,不添加新类型),接口声明类之间的唯一区别就是你不能一个界面。但是,如果您打算 extend / 实现这些类型中的一个在新的,你必须在接口声明类之间正确选择。只有其中一个可以使用。

From a pure consumption side (writing imperative code, not adding new types), the only difference between interface and declare class is that you can't new an interface. However, if you intend to extend/implement one of these types in a new class, you absolutely have to have chosen correctly between interface and declare class. Only one of them will work.

两个适合你的规则:


  • 类型的名称是否与运行时实际存在的构造函数(可以用 new 调用的东西)对齐(例如 Date 是,但 JQueryStatic 不是)?如果 no ,你肯定想要接口

  • 我是否正在处理来自另一个TypeScript文件的编译类,或类似的东西?如果,请使用声明类

  • Is the name of the type aligning with a constructor function (something invokable with new) that's actually present at runtime (e.g. Date is, but JQueryStatic is not)? If no, you definitely want interface
  • Am I dealing with a compiled class from another TypeScript file, or something sufficiently similar? If yes, use declare class

这篇关于“声明类”之间的区别是什么?和“界面”在TypeScript中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆