VJAI
VJAI

Reputation: 32758

Cannot use new with expression typescript

interface Window {
    AudioContext: AudioContext;
    webkitAudioContext: Function
}

let contextClass = window.AudioContext || window.webkitAudioContext;
let context: AudioContext = new contextClass();

The last line is giving me this error,

Cannot use 'new' with an expression whose type lacks a call or construct signature

How can I resolve this?

Upvotes: 43

Views: 62001

Answers (2)

haim770
haim770

Reputation: 49095

The problem is that the compiler treats the contextClass variable as an instance of AudioContext while in fact it's merely a constructor function for an AudioContext.

You can simply use any and the compiler will let you new it:

let contextClass : any = window.AudioContext || window.webkitAudioContext;
let context: AudioContext = new contextClass();

Another option would be to introduce a Constructable<T> interface that will let you new up those types:

interface Constructable<T> {
    new(...args: any) : T;
}

interface Window
{
    AudioContext: Constructable<AudioContext>;
    webkitAudioContext: Constructable<AudioContext>
}

let contextClass = window.AudioContext || window.webkitAudioContext;
let context: AudioContext = new contextClass();

Upvotes: 53

Nathan
Nathan

Reputation: 6531

You can't new up an instance. new instanceofAudioContext() isn't a valid thing to do.

Your interface doesn't match the API you're trying to use. In the browser, window.AudioContext isn't a instance of AudioContext. It's the class definition method, typeof AudioContext. You'll also have the same problem with the Function.

If you'd still like to keep your interface. Try this

interface Window {
    AudioContext: typeof AudioContext;
    webkitAudioContext: typeof AudioContext
}

declare var window: Window;

var AudioContextDecl = window.AudioContext || window.webkitAudioContext;
var audioCtx = new AudioContext();

Or if you don't want the interface,

var AudioContextDecl = <typeof AudioContext>(window.AudioContext || window.webkitAudioContext);
var audioCtx = new AudioContext();

Or even just use any. It all transpiles to the same thing.

Upvotes: 13

Related Questions