简体   繁体   中英

Typescript ambient declaration namespace

Recently i have moved our spa app to typescript,and now i stuck with implementing the declation file of rsa.js which is used for openid authentication.

Previously used Js code like below.

var jws = new KJUR.jws.JWS();
jws.verifyJWSByPemX509Cert(idToken, cert);

in a rsa.d.ts file

declare namespace KJUR.jws {
    interface IParsedJWS {
        payloadS: any
    }
    interface IJWS {
        new ();
        verifyJWSByPemX509Cert(idToken: string, cert: string): boolean;
        parsedJWS: IParsedJWS;
    }
}

declare var JWS: KJUR.jws.IJWS;
declare module "KJUR.jws.JWS" {
    export = JWS;
}

Im not sure what im doing here.Please anyone guide me the right way.How can i define namespace like KJUR.jws.JWS to use new KJUR.jws.JWS();?

Thanks

First up, there's a bug in your IJWS interface definition. It defines a class-like object (something with a constructor), but it doesn't say what the constructor returns, and the methods defined are attached to the interface (ie the class itself), not the the object returned by the constructor. What you really want here is a class definition, not an interface:

class JWS {
    verifyJWSByPemX509Cert(idToken: string, cert: string): boolean;
    parsedJWS: IParsedJWS;
}

This more accurately represents what you actually have. Once you've got that it's easy, you just need to export the class from inside the module ( playground link ):.

declare namespace KJUR.jws {
    interface IParsedJWS {
        payloadS: any
    }

    export class JWS {
        verifyJWSByPemX509Cert(idToken: string, cert: string): boolean;
        parsedJWS: IParsedJWS;
    }
}

This works if you want to define an 'ambient' module: a module that doesn't need explicit loading (ie types representing a global that's already going to exist at runtime).

If you want to make this a module loadable by name, through Node modules/RequireJS/etc, you just need to move that definition into a separate file, use a module instead of a namespace, and add quotes around the name, as below playground :

// In a separate file, e.g. "KJUR.d.ts":
declare module "KJUR.jws" {
    interface IParsedJWS {
        payloadS: any
    }

    export class JWS {
        verifyJWSByPemX509Cert(idToken: string, cert: string): boolean;
        parsedJWS: IParsedJWS;
    }
}

// Elsewhere:

// (The string below and the module name above need to match what RequireJS
// is expecting, or it'll compile, but fail to find the module at runtime.
// You can change them to anything you like, as long as they match.) 
import jws = require("KJUR.jws");

var idToken: string;
var cert: string;

var jws = new jws.JWS();
jws.verifyJWSByPemX509Cert(idToken, cert);

The key difference is how this KJUR object actually gets loaded in JavaScript at runtime. If you need a module to be actively loaded for it to become available, you need to use the named module syntax (the 2nd option above). If it's a global that's already going to exist (you've got a script tag that already adds it) then you should just use the first option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM