Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot use new with expression typescript

Tags:

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?

like image 202
VJAI Avatar asked Dec 07 '16 12:12

VJAI


2 Answers

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();
like image 62
haim770 Avatar answered Nov 04 '22 17:11

haim770


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.

like image 11
Nathan Cooper Avatar answered Nov 04 '22 19:11

Nathan Cooper