正确使用Typescript .d.ts文件

时间:2016-09-24 13:01:58

标签: typescript visual-studio-2015 typescript-typings

我正试图了解TypeScript .d.ts文件的工作原理。我很难掌握以下似乎存在的差异:

  1. 编译器
  2. Intellisense(在VS2015中使用ReSharper)
  3. 运行时/模块加载器(Systemjs)
  4. 我正在使用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>指向正确的文件):

    1. 编译器会抱怨new Oidc.UserManager()调用
    2. 上没有Oidc名称空间
    3. Intellisense也抱怨缺少Oidc符号
    4. 不编译,所以也不运行
    5. 因此,为了取悦编译器,我可以将代码更改为此(注意从new Oidc.UserManagernew 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
              });
          }
      }
      

      这具有以下效果:

      1. 编译器将不再抱怨
      2. Intellisense也很高兴
      3. 运行应用程序时,出现错误,指出UserManager不存在。这是正确的,因为在oidc-client-js库中,所有类实际上都在Oidc命名空间中。因此,创建对象的正确方法是new Oidc.UserManager()
      4. 解决此问题的另一种方法是将代码更改为此(请注意添加的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
                });
            }
        }
        

        这将:

        1. 让编译器开心
        2. 欺骗智能感知Oidc下的任何东西都是any类型,这显然不是最优的。
        3. 在运行时正常工作
        4. 到目前为止我发现的唯一可以在所有方面工作的解决方案是将.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中如何工作的正确理解。

          任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

我认为这只是定义文件的一个问题。

定义文件说应该有var UserManager: Oidc.UserManager可用。这就是编译器在您使用new UserManager()时没有抱怨的原因,因为定义文件说它存在。

问题是它实际上不存在(在JavaScript中),因此运行时错误。

此文件可能不正确,因为它已过时。我发现了一个看似updated definition file的内容,您可能需要尝试一下。