简体   繁体   中英

How to define a Typescript constructor and factory function with the same name?

I am writing a Typescript definition file for an existing Javascript library . In this library there are functions which can be called as constructors or factories. How do I write the typings in a compatible fashion?

Here is a specific example of the calls that need to be supported according to the README :

var streamParser = N3.StreamParser();
var streamParser = new N3.StreamParser();

My current approach is to only support the factory.

function Parser(options?: ParserOptions): N3Parser;

The obvious approach to get the new to work is to create a class.

class Parser {
  constructor(options ? : ParserOptions);
}

But these two approaches are incompatible. The opening paragraph of the declartion-file deep-dive indicates this is possible but no example is given.

Note: The following two definitions are compatible but... so, what?

interface Parser {
  new: (options ? : ParserOptions) => N3Parser;
}

function Parser(options ? : ParserOptions): N3Parser;

You can follow the same thing that is done in the lib.d.ts with Array and ArrayConstructor :

interface Parser {}

interface ParserConstructor {
    new (options?: ParserOptions): Parser;
    (options?: ParserOptions): Parser;
}

declare const Parser: ParserConstructor;

let p1 = Parser();
let p2 = new Parser();

( code in playground )

Nitzan Tomer's answer is spot-on.

For my particular case the object constructed has an different interface and the constructor needs some overloading. The following sample shows how the constructor interface can easily support these requirements.

interface N3Parser { }
interface ParserOptions {[key: string]: string }

interface ParserConstructor {
    new (options?: ParserOptions): N3Parser;
    (options?: ParserOptions): N3Parser;

    new (fd: any, options?: ParserOptions): N3Parser;
    (fd: any, options?: ParserOptions): N3Parser;
}
declare const Parser: ParserConstructor;

let p1 = Parser();
let p2 = new Parser();

let p3 = Parser({ x: "y" });
let p4 = new Parser(3, { x: "y" });

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