2

I have some simple popstate code for an SPA as follows:

module myModule {
    $(function () {
        $(window).on("popstate", function(e) {
            if (e.originalEvent.state !== null) {
                // code removed
            }
        });
    });
}

(The use of originalEvent is due to answers like this: popstate returns event.state is undefined)

This gives a compile error:

Property 'state' does not exist on type 'Event'.

e is a JQueryEventObject type and originalEvent is an Event type.

Now I've managed to work around the problem by defining this interface:

interface EventWithState extends Event {
    state: any;
}

(*I doubt "any" is really my best option here - if anyone knows what type state should be let me know, and more importantly how do I find that out for myself in such cases)

And I changed my above code like so:

module myModule {
    $(function () {
        $(window).on("popstate", function(e) {
            if ((<EventWithState>e.originalEvent).state !== null) {
                // code removed
            }
        });
    });
}

OK that works fine now and compiles to the original code I wanted. But it seems like an awkward workaround.

Is this the acceptable method to do this? Is something missing from typescript definitions? Or is there something I am missing.

Furthermore using e.state also doesn't work, however editing jquery.d.ts (from DefinitelyTyped) and adding state: any; to BaseJQueryEventObject fixes it in a similar way to my workaround. This is what makes me think something is missing from definitions for typescript regarding the Event state.

Community
  • 1
  • 1
braks
  • 1,267
  • 11
  • 21

1 Answers1

3

Thanks to Pilot for sharing the answer to another question, though it seemed unrelated at first, it did hold the clues and links for me to work out that I could cast to PopStateEvent rather than my own EventWithState.

module myModule {
    $(function () {
        $(window).on("popstate", function(e) {
            if ((<PopStateEvent>e.originalEvent).state !== null) {
                // code removed
            }
        });
    });
}

https://developer.mozilla.org/en-US/docs/Web/API/Event

https://developer.mozilla.org/en-US/docs/Web/API/PopStateEvent

And for the record, lib.d.ts does use "any" as the type for state:

interface PopStateEvent extends Event {
    state: any;
    initPopStateEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, stateArg: any): void;
}

https://typescript.codeplex.com/SourceControl/latest#bin/lib.d.ts

braks
  • 1,267
  • 11
  • 21