Javascript Typescript声明文件包含没有成员实现的类定义

Javascript Typescript声明文件包含没有成员实现的类定义,javascript,typescript,Javascript,Typescript,当我查看主干声明文件时,我看到: export class Router extends Events { ... constructor (options?: RouterOptions); initialize (options?: RouterOptions); ... } 以及类具有方法定义但没有实现的其他地方。我认为这个语法是为接口保留的。编译器允许在声明文件中传递,但不允许在我自己的ts文件中传递 .d.ts和.ts扩展的编译规则之间有区别吗?如果是

当我查看主干声明文件时,我看到:

export class Router extends Events {
    ...
    constructor (options?: RouterOptions);
    initialize (options?: RouterOptions);
    ...
}
以及类具有方法定义但没有实现的其他地方。我认为这个语法是为接口保留的。编译器允许在声明文件中传递,但不允许在我自己的ts文件中传递


.d.ts和.ts扩展的编译规则之间有区别吗?如果是这样,这些类型的类应该如何与接口不同地使用?

如果文件具有
.d.ts
扩展名,则所有类都被视为前面有
declare
关键字。声明不需要实现,它们只提供类型信息。

.d.ts
文件用于描述某个类的现有JavaScript或TypeScript实现

.d.ts
中的类(我将其称为“
声明类
”,因为它们是等效的)与虚拟类或接口完全不同。当您声明一个
声明类时,您的意思是“将存在具有此形状的其他类”。当您
扩展该类时,
编译器将发出代码,前提是在运行时确实会有一个具有该名称的类(或足够类似类的东西)作为原型链中的下一个指针

例如,此代码(本身)不起作用-您将得到一个运行时错误,因为
Foo
未在任何地方定义:

declare class Foo {  public bar(): void; }
class FooDerived extends Foo { }
另一方面,此代码很好:

interface Foo { bar(): void; }
class FooImpl implements Foo { public bar() {} }

除了在实现时需要使用“extends”而不是“implements”之外,这个构造与接口有什么不同?在我看来,它类似于一个虚拟类,因为在扩展这个类时,编译器不会抱怨没有提供实现。我假设唯一的区别是base.initialize()不能被调用。这是正确的吗?谢谢你的回复。为了让我自己看看,我扩展了一个“declare类”,它与扩展一个空类“class SomeClass{}”完全一样。我将研究编译器为模拟继承而发出的“原型链”代码,这有点令人困惑。回答得好,谢谢。但是等等,这似乎是个问题。intellisense很好,但是当我从继承这个declare类的类的实例调用initialize()时会发生什么呢?编译器允许它通过,但没有实现此方法,甚至在生成的javascript中也没有。因此,它不会在运行时崩溃吗?编写
声明类
意味着“编译器,我要告诉您的是一个已经存在的类;请不要在这里生成代码,但要像该类将在运行时出现一样行事”。如果您编写
声明类
,但实际上没有可从中继承的类,那将是一个运行时错误。很抱歉,从实际角度看,这对我来说没有意义。我没有编写任何declare类,我知道.d.ts文件实际上不会生成任何代码。您评论的最后一行建议我应该为整个声明文件中的每个声明类编写一个实现。为什么我要从“declare class”继承,而不是从接口或常规类继承,这样实际上可以防止运行时错误?我可以将其与“declare var$:JQueryStatic”进行比较。为了智能感知,我在这里声明$JQueryStatic类型,如果我不提供实现(加载jQuery库),它将在运行时崩溃。从“declare类”继承时也是如此。我“承诺”在尝试使用之前为成员提供实现,但是如果我不这样做,它将在运行时崩溃。最终我看不出这种构造是如何有益的。“declare var$:JQueryStatic”仅用于为非您编写的外部非类型脚本库提供类型信息。