Reputation: 720
Function Register is instantiated by calling Register('something')
. Typescript says this is only possible if new
is used on a void
returning function . In this case Register
is returning an instance of itself. How should I type this in Typescript?
module Register {
export function Register(x: string): Instance {
if (!(this instanceof Register)) {
return new Register(x)
}
this.value = x
}
...
export interface Instance {
new(x: string): Instance;
...
}
}
export = Register
Upvotes: 3
Views: 8662
Reputation: 7234
I suspect you're having the same problem that I ran into (that brought me here).
I was trying to add some TypeScript type definitions (.d.ts
) for an existing pure JavaScript (.js
) project.
The JavaScript source was a traditional constructor
function (with prototype class methods) that detected if it was called without new
and did the right thing:
const MyObject = function (options) {
if (!(this instanceof MyObject)) {
return new MyObject(options);
}
// ...
}
MyObject.prototype.myMethod = function() {
// Do something...
}
module.exports = MyObject;
My understanding of the "correct" way to add TypeScript types for this kind of JavaScript object is with an interface
:
declare interface MyObject {
/**
* Constructor interface
*/
new (options?: Options): this;
/**
* Functional interface
*/
(options?: Options): this;
/**
* JSDoc ftw!
*/
myMethod(): void;
}
// Needed so we can export a variable, not just a type
declare const MyObject: MyObject;
// Since the JavaScript is not exporting a "module" (object with a `default` parameter):
export = MyObject;
Upvotes: 0
Reputation: 14274
Maybe your example is simplified, and you are trying to achieve something more complex under the hood, but If i understand your code correctly you just want to return an instance of the Register function without the New operator.
The only option i can think of is to trick the TS compiler, and to specify the return type as void, and then in your variables use type any.
module Register {
export function Register(x: string): void {
if (!(this instanceof Register)) {
return new Register(x);
}
this.value = x;
}
export interface Instance {
new (x: string): Instance;
value: string;
}
}
export = Register;
var rega: any = Register.Register("something");
console.log(rega.value); // something
Update: Since you have a problem with specifying any
as the explicit type for each variable, then you could use Object.create() instead of the new operator:
module Register {
export function Register(x: string): Instance {
var r = Object.create(Register);
r.value = x;
return r;
}
export interface Instance {
new (x: string): Instance;
value: string;
}
}
export = Register;
var rega = Register.Register("something");
console.log(rega.value); // something
Upvotes: 1