我想弄清楚typescript.d.ts文件到底是如何工作的。我很难掌握似乎存在于两者之间的差异:
编译器
智能感知(在VS2015与RESARPER)
运行时/模块加载程序
我使用的是oidc client js库,它提供了一个类似于下面的oidc-client.d.ts文件:
declare var UserManager: Oidc.UserManager;
... more stuff
declare module "oidc-client" {
export = Oidc;
}
declare namespace Oidc {
interface OidcClient {
... more stuff
}
interface OidcManager extends OidcClient {
... more stuff
}
... more stuff
}
我想在自己的typescript类中使用usermanager类,因此执行以下操作:
/// <reference path="../node_modules/oidc-client/oidc-client.d.ts"/>
export class SecurityService {
private manager: Oidc.UserManager;
constructor() {
this.manager = new Oidc.UserManager({
... settings here
});
}
}
此时会发生以下情况(
<reference>
指向正确的文件):编译器将抱怨
new Oidc.UserManager()
调用上没有oidc命名空间智能感知还抱怨丢失的OIDC符号。
不编译,所以也不运行
为了取悦编译器,我可以把代码改成这样(注意从
new Oidc.UserManager
改成new UserManager
:/// <reference path="../node_modules/oidc-client/oidc-client.d.ts"/>
export class SecurityService {
private manager: Oidc.UserManager;
constructor() {
this.manager = new UserManager({
... settings here
});
}
}
这具有以下效果:
编译器将不再抱怨
智力也是快乐的
当运行应用程序时,我会发现一个错误,说明不存在。这是正确的,因为在oidc客户端js库中,所有类实际上都在oidc名称空间中。因此,创建对象的正确方法是
new Oidc.UserManager()
。解决此问题的另一种方法是将代码更改为(注意添加的
declare var Oidc
:/// <reference path="../node_modules/oidc-client/oidc-client.d.ts"/>
declare var Oidc;
export class SecurityService {
private manager: Oidc.UserManager;
constructor() {
this.manager = new Oidc.UserManager({
... settings here
});
}
}
这将:
让编译器高兴
诡计多端的智能感知,认为Oidc下的任何东西都属于
any
类型,这明显小于最优。运行时工作精细
到目前为止,我发现的唯一一个在所有方面都有效的解决方案是将.d.ts文件更改为使用类而不是接口:
declare var UserManager: Oidc.UserManager;
... more stuff
declare module "oidc-client" {
export = Oidc;
}
declare namespace Oidc {
class OidcClient {
... more stuff
}
class OidcManager extends OidcClient {
... more stuff
}
... more stuff
}
但这需要更改定义文件。看看其他定义文件,它们通常使用接口而不是类,所以这让我怀疑这是否是定义文件的问题,或者这是否只是我对typescript中的工作方式缺乏正确的理解。
任何帮助都将不胜感激。
最佳答案
我想这只是定义文件的问题。
定义文件说应该有一个var UserManager: Oidc.UserManager
可用。这就是为什么编译器在使用new UserManager()
时不会抱怨,因为定义文件说它存在。
问题是它实际上不存在(在javascript中),因此出现运行时错误。
此文件可能不正确,因为它已过时。我找到了一个看似updated definition file,你可能想试试。