typescriptgulpgulp-typescript

TypeScript error TS2339: Property 'matches' does not exist on type 'EventTarget'


I'm getting an error that I just cannot fathom from TypeScript. I'm using a perfectly valid piece of JavaScript but it's flagging an error, both in my IDE and during pre-processing via Gulp.

I've stripped it back to its core and I'm still getting an error (even though this is perfectly valid JS).

document.addEventListener('click', function (event) {
    console.log(event.target.matches('.click-me'));
}, false);

TypeScript fails compilation with the following error:

error TS2339: Property 'matches' does not exist on type 'EventTarget'.

I've checked my TypeScript options and they should allow me to use "matches" without issue.

let tscOptions = {
    allowSyntheticDefaultImports: true,
    target: "es5",
    lib: [
        "dom",
        "es7",
        "scripthost",
        "es2017"
    ],
    module: "commonjs"
};

I'm using version 4.1.2 of TypeScript and v6.0.0-alpha.1 of Gulp Typescript.

It's obviously a configuration issue somewhere, but I don't know where.


Solution

  • First - it depends on how you define valid JS! Yes - your JS will work (almost all?) of the time, but this doesn't mean it's guaranteed 100% of the time.

    The problem here is that .matches is a property of objects of type Element. event can be null - and event.target is either null or an EventTarget.

    An Element (the type you want) extends the Node type, which extends the EventTarget type. So, you're not guaranteed to be getting the type you expect, therefore TS is correct to warn you.

    It may be perfectly suitable for your use-case to ignore these warnings however - in which case you can just cast it:

    
    document.addEventListener('click', function (event) {
        if (event !== null && event.target !== null) {
           const element = event.target as Element;
    
           const isMatch = element.matches('foo');
        }
    }, false);
    

    There's not much point in writing tons of logic to verify for every edge case IMO - but you can learn more about the issue here: https://github.com/Microsoft/TypeScript/issues/29540