microsoft / microsoft/TypeScript

DOM: `Element#matches()` incorrectly narrows types

Open
#63,497 14 comments 3 reactions 0 assignees View on GitHub
Domain: lib.d.ts Help Wanted
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

### 🔎 Search Terms

element matches narrow never

### 🕗 Version & Regression Information

- This changed between versions 5.9.3 and 6.0.3

### ⏯ Playground Link

https://www.typescriptlang.org/play/?ts=6.0.3#code/CYUwxgNghgTiAEEQBd4iQWxAO2QLngAkAVAWQBkBRTHZAbgCgBCdELXAOgymTAAsQAZwAU8AOTBkY+AEp4AMnloanbrwEjxwYNJlA

### 💻 Code

```ts
declare let element: HTMLElement;
!element.matches( 'dt' ) && element.matches( 'dd' )
```

### 🙁 Actual behavior

`element.matches( 'dd' )` throws a `Property 'matches' does not exist on type 'never'` compilation error.

### 🙂 Expected behavior

`element.matches( 'dd' )` does not throw any error.

### Additional information about the issue

`element.matches( 'dt' )` uses the following overload:
```ts
matches(selectors: K): this is HTMLElementTagNameMap[K];
```

The return type of `element.matches( 'dt' )` is then `this is HTMLElementTagNameMap['dt']` that maps to `this is HTMLElement`.

Since `this` is `HTMLElement`:
- When false, the type of `element` is `HTMLElement` (not narrowed further).
- When false, the type of `element` is `never`.

Contributor guide

Open the contributing guide

Research direction

Start with the linked TypeScript Playground example and inspect the Element#matches overload shown in the issue, then trace how the type predicate narrows HTMLElement after a negated check. The issue is complete when the second element.matches('dd') call compiles without a Property 'matches' does not exist on type 'never' error.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.