Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript call function that may not exist at compile time

Tags:

typescript

I am trying to write a library that checks for a callback function and then calls it when it is ready. The idea being that you can include the JS asynchronously and then when it's loaded it will check for the callback and execute it.

I'm using typescript. The following JS works but wont compile in TS

if(typeof myFramework.ready === 'function') {
    myFramework.ready();
}

Then the developer using the library could do the following:

var myFramework = myFramework || {}; // As the framework wont exists
myFramework.ready = function(){//Execute developer's code};

However, using TypeScript I'm getting a type error: Property 'ready' does not exist on type 'typeof myFramework' - which is not a surprise. It does compile if I do the following:

interface Window {
    ready(): void;
}

if(typeof window.ready === 'function') {
    window.ready();
}

But that would mean adding more crud to the window object. And I imagine calling a global ready() method could well be a point of failure!

How would you go about achieving this?


Thanks to @james-crosswell - as I have classes in separate files the file that had the Ajax handling bit in looked something like:

module MyFramework {
    export interface IMyFramework {
        ready? : () => any;
    }

    export class HasLoaded implements IMyFramework {
        doReady = (framework: IMyFramework) => {
            if(typeof framework.ready === 'function') {
                framework.ready();
            }
        }
    }

    var newHost: HasLoaded = new HasLoaded();
    newHost.doReady(MyFramework);
}

I may be rethinking the logic that got me here but that's a separate issue!

like image 608
Ed Evans Avatar asked Jun 13 '26 07:06

Ed Evans


1 Answers

myFramework.ready?.();

I think is the most compact and resembles C# syntax. It uses the optional chaining operator (?.)

================

Some comments on the other answers:

Why not this?

if (!!myFramework.ready) {
    myFramework.ready();
}

(the classic double exclamation mark construct -- the first exclamation mark transforms 'undefined' into true, the second one turns it back to false (hence converting 'undefined' to a valid false boolean)

Please note : ESLint doesn't like this construct:

myFramework.ready && myFramework.ready();

(or this equivalent one)

!!myFramework.ready && myFramework.ready();

It says : "Expected an assignment or function call and instead saw an expression"

That's because ready is a method, so Typescript wonders if it's by mistake that you're not calling it and not assigning it -- and instead checking its value, as if it were a variable/an expression.

like image 164
jeancallisti Avatar answered Jun 15 '26 00:06

jeancallisti



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!