我想弄清楚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,你可能想试试。

09-19 03:49