diff --git a/src/__tests__/helpers/dom-event-map.d.ts b/src/__tests__/helpers/dom-event-map.d.ts
new file mode 100644
index 00000000..ed4007a3
--- /dev/null
+++ b/src/__tests__/helpers/dom-event-map.d.ts
@@ -0,0 +1,9 @@
+declare module '@testing-library/dom/dist/event-map' {
+  export const eventMap: Record<
+    string,
+    {
+      EventType: string
+      defaultInit: EventInit
+    }
+  >
+}
diff --git a/src/__tests__/helpers/utils.js b/src/__tests__/helpers/utils.ts
similarity index 59%
rename from src/__tests__/helpers/utils.js
rename to src/__tests__/helpers/utils.ts
index 36a4e474..5f0c36fb 100644
--- a/src/__tests__/helpers/utils.js
+++ b/src/__tests__/helpers/utils.ts
@@ -7,25 +7,48 @@ import {isElementType} from '../../utils'
 // all of the stuff below is complex magic that makes the simpler tests work
 // sorrynotsorry...
 
-const unstringSnapshotSerializer = {
-  test: val => val && val.hasOwnProperty('snapshot'),
-  print: val => val.snapshot,
+const unstringSnapshotSerializer: jest.SnapshotSerializerPlugin = {
+  test: (val: unknown) =>
+    Boolean(
+      typeof val === 'object'
+        ? Object.prototype.hasOwnProperty.call(val, 'snapshot')
+        : false,
+    ),
+  print: val => String((<null | {snapshot?: string}>val)?.snapshot),
 }
 
 expect.addSnapshotSerializer(unstringSnapshotSerializer)
 
-function setup(ui, {eventHandlers} = {}) {
+type EventHandlers = Record<string, EventListener>
+
+// The HTMLCollection in lib.d.ts does not allow array access
+type HTMLCollection<Elements extends Array<Element>> = Elements & {
+  item<N extends number>(i: N): Elements[N]
+}
+
+function setup<Elements extends Element | Element[] = HTMLElement>(
+  ui: string,
+  {
+    eventHandlers,
+  }: {
+    eventHandlers?: EventHandlers
+  } = {},
+) {
   const div = document.createElement('div')
   div.innerHTML = ui.trim()
   document.body.append(div)
 
+  type ElementsArray = Elements extends Array<Element> ? Elements : [Elements]
   return {
-    element: div.firstChild,
-    elements: div.children,
+    element: div.firstChild as ElementsArray[0],
+    elements: div.children as unknown as HTMLCollection<ElementsArray>,
     // for single elements add the listeners to the element for capturing non-bubbling events
-    ...addListeners(div.children.length === 1 ? div.firstChild : div, {
-      eventHandlers,
-    }),
+    ...addListeners(
+      div.children.length === 1 ? (div.firstChild as Element) : div,
+      {
+        eventHandlers,
+      },
+    ),
   }
 }
 
@@ -49,7 +72,7 @@ function setupSelect({
     </select>
   `
   document.body.append(form)
-  const select = form.querySelector('select')
+  const select = form.querySelector('select') as HTMLSelectElement
   const options = Array.from(form.querySelectorAll('option'))
   return {
     ...addListeners(select),
@@ -76,17 +99,22 @@ function setupListbox() {
     </ul>
   `
   document.body.append(wrapper)
-  const listbox = wrapper.querySelector('[role="listbox"]')
-  const options = Array.from(wrapper.querySelectorAll('[role="option"]'))
+  const listbox = wrapper.querySelector('[role="listbox"]') as HTMLUListElement
+  const options = Array.from(
+    wrapper.querySelectorAll<HTMLElement>('[role="option"]'),
+  )
 
   // the user is responsible for handling aria-selected on listbox options
   options.forEach(el =>
-    el.addEventListener('click', e =>
-      e.target.setAttribute(
+    el.addEventListener('click', e => {
+      const target = e.currentTarget as HTMLElement
+      target.setAttribute(
         'aria-selected',
-        JSON.stringify(!JSON.parse(e.target.getAttribute('aria-selected'))),
-      ),
-    ),
+        JSON.stringify(
+          !JSON.parse(String(target.getAttribute('aria-selected'))),
+        ),
+      )
+    }),
   )
 
   return {
@@ -97,7 +125,7 @@ function setupListbox() {
 }
 
 const eventLabelGetters = {
-  KeyboardEvent(event) {
+  KeyboardEvent(event: KeyboardEvent) {
     return [
       event.key,
       typeof event.keyCode === 'undefined' ? null : `(${event.keyCode})`,
@@ -105,9 +133,9 @@ const eventLabelGetters = {
       .join(' ')
       .trim()
   },
-  MouseEvent(event) {
+  MouseEvent(event: MouseEvent) {
     // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
-    const mouseButtonMap = {
+    const mouseButtonMap: Record<number, string> = {
       0: 'Left',
       1: 'Middle',
       2: 'Right',
@@ -116,20 +144,29 @@ const eventLabelGetters = {
     }
     return `${mouseButtonMap[event.button]} (${event.button})`
   },
-}
+} as const
 
-let eventListeners = []
+let eventListeners: Array<{
+  el: EventTarget
+  type: string
+  listener: EventListener
+}> = []
 
 // asside from the hijacked listener stuff here, it's also important to call
 // this function rather than simply calling addEventListener yourself
 // because it adds your listener to an eventListeners array which is cleaned
 // up automatically which will help use avoid memory leaks.
-function addEventListener(el, type, listener, options) {
+function addEventListener(
+  el: EventTarget,
+  type: string,
+  listener: EventListener,
+  options?: AddEventListenerOptions,
+) {
   eventListeners.push({el, type, listener})
   el.addEventListener(type, listener, options)
 }
 
-function getElementValue(element) {
+function getElementValue(element: Element) {
   if (isElementType(element, 'select') && element.multiple) {
     return JSON.stringify(Array.from(element.selectedOptions).map(o => o.value))
   } else if (element.getAttribute('role') === 'listbox') {
@@ -139,25 +176,38 @@ function getElementValue(element) {
   } else if (element.getAttribute('role') === 'option') {
     return JSON.stringify(element.innerHTML)
   } else if (
-    element.type === 'checkbox' ||
-    element.type === 'radio' ||
+    isElementType(element, 'input', {type: 'checkbox'}) ||
+    isElementType(element, 'input', {type: 'radio'}) ||
     isElementType(element, 'button')
   ) {
     // handled separately
     return null
   }
 
-  return JSON.stringify(element.value)
+  return JSON.stringify((element as HTMLInputElement).value)
 }
 
-function getElementDisplayName(element) {
+function hasProperty<T extends {}, K extends PropertyKey>(
+  obj: T,
+  prop: K,
+): obj is T & {[k in K]: unknown} {
+  return prop in obj
+}
+
+function getElementDisplayName(element: Element) {
   const value = getElementValue(element)
-  const hasChecked = element.type === 'checkbox' || element.type === 'radio'
+  const hasChecked =
+    isElementType(element, 'input', {type: 'checkbox'}) ||
+    isElementType(element, 'input', {type: 'radio'})
   return [
     element.tagName.toLowerCase(),
     element.id ? `#${element.id}` : null,
-    element.name ? `[name="${element.name}"]` : null,
-    element.htmlFor ? `[for="${element.htmlFor}"]` : null,
+    hasProperty(element, 'name') && element.name
+      ? `[name="${element.name}"]`
+      : null,
+    hasProperty(element, 'htmlFor') && element.htmlFor
+      ? `[for="${element.htmlFor}"]`
+      : null,
     value ? `[value=${value}]` : null,
     hasChecked ? `[checked=${element.checked}]` : null,
     isElementType(element, 'option') ? `[selected=${element.selected}]` : null,
@@ -169,13 +219,44 @@ function getElementDisplayName(element) {
     .join('')
 }
 
-function addListeners(element, {eventHandlers = {}} = {}) {
-  const eventHandlerCalls = {current: []}
+type CallData = {
+  event: Event
+  elementDisplayName: string
+  testData?: TestData
+}
+
+type TestData = {
+  handled?: boolean
+
+  // Where is this assigned?
+  before?: Element
+  after?: Element
+}
+
+function isElement(target: EventTarget): target is Element {
+  return 'tagName' in target
+}
+
+function isMouseEvent(event: Event): event is MouseEvent {
+  return event.constructor.name === 'MouseEvent'
+}
+
+function addListeners(
+  element: Element & {testData?: TestData},
+  {
+    eventHandlers = {},
+  }: {
+    eventHandlers?: EventHandlers
+  } = {},
+) {
+  const eventHandlerCalls: {current: CallData[]} = {current: []}
   const generalListener = jest
-    .fn(event => {
-      const callData = {
+    .fn((event: Event) => {
+      const target = event.target
+      const callData: CallData = {
         event,
-        elementDisplayName: getElementDisplayName(event.target),
+        elementDisplayName:
+          target && isElement(target) ? getElementDisplayName(target) : '',
       }
       if (element.testData && !element.testData.handled) {
         callData.testData = element.testData
@@ -192,10 +273,9 @@ function addListeners(element, {eventHandlers = {}} = {}) {
 
   for (const name of listeners) {
     addEventListener(element, name.toLowerCase(), (...args) => {
-      const handler = eventHandlers[name]
-      if (handler) {
+      if (name in eventHandlers) {
         generalListener(...args)
-        return handler(...args)
+        return eventHandlers[name](...args)
       }
       return generalListener(...args)
     })
@@ -208,10 +288,15 @@ function addListeners(element, {eventHandlers = {}} = {}) {
   function getEventSnapshot() {
     const eventCalls = eventHandlerCalls.current
       .map(({event, testData, elementDisplayName}) => {
+        const eventName = event.constructor.name
         const eventLabel =
-          eventLabelGetters[event.constructor.name]?.(event) ?? ''
+          eventName in eventLabelGetters
+            ? eventLabelGetters[eventName as keyof typeof eventLabelGetters](
+                event as KeyboardEvent & MouseEvent,
+              )
+            : ''
         const modifiers = ['altKey', 'shiftKey', 'metaKey', 'ctrlKey']
-          .filter(key => event[key])
+          .filter(key => event[key as keyof Event])
           .map(k => `{${k.replace('Key', '')}}`)
           .join('')
 
@@ -245,18 +330,17 @@ function addListeners(element, {eventHandlers = {}} = {}) {
     generalListener.mockClear()
     eventHandlerCalls.current = []
   }
-  const getEvents = type =>
+  const getEvents = (type?: string) =>
     generalListener.mock.calls
       .map(([e]) => e)
       .filter(e => !type || e.type === type)
-  const eventWasFired = eventType => getEvents().some(e => e.type === eventType)
+  const eventWasFired = (eventType: string) => getEvents(eventType).length > 0
 
   function getClickEventsSnapshot() {
-    const lines = getEvents().map(
-      ({constructor, type, button, buttons, detail}) =>
-        constructor.name === 'MouseEvent'
-          ? `${type} - button=${button}; buttons=${buttons}; detail=${detail}`
-          : type,
+    const lines = getEvents().map(e =>
+      isMouseEvent(e)
+        ? `${e.type} - button=${e.button}; buttons=${e.buttons}; detail=${e.detail}`
+        : e.type,
     )
     return {snapshot: lines.join('\n')}
   }
@@ -270,21 +354,23 @@ function addListeners(element, {eventHandlers = {}} = {}) {
   }
 }
 
-function getValueWithSelection({value, selectionStart, selectionEnd}) {
+function getValueWithSelection(element?: Element) {
+  const {value, selectionStart, selectionEnd} = element as HTMLInputElement
+
   return [
-    value.slice(0, selectionStart),
+    value.slice(0, selectionStart ?? undefined),
     ...(selectionStart === selectionEnd
       ? ['{CURSOR}']
       : [
           '{SELECTION}',
-          value.slice(selectionStart, selectionEnd),
+          value.slice(selectionStart ?? 0, selectionEnd ?? undefined),
           '{/SELECTION}',
         ]),
-    value.slice(selectionEnd),
+    value.slice(selectionEnd ?? undefined),
   ].join('')
 }
 
-const changeLabelGetter = {
+const changeLabelGetter: Record<PropertyKey, (d: TestData) => string> = {
   value: ({before, after}) =>
     [
       JSON.stringify(getValueWithSelection(before)),
@@ -292,8 +378,8 @@ const changeLabelGetter = {
     ].join(' -> '),
   checked: ({before, after}) =>
     [
-      before.checked ? 'checked' : 'unchecked',
-      after.checked ? 'checked' : 'unchecked',
+      (before as HTMLInputElement).checked ? 'checked' : 'unchecked',
+      (after as HTMLInputElement).checked ? 'checked' : 'unchecked',
     ].join(' -> '),
 
   // unfortunately, changing a select option doesn't happen within fireEvent
@@ -303,16 +389,28 @@ const changeLabelGetter = {
 }
 changeLabelGetter.selectionStart = changeLabelGetter.value
 changeLabelGetter.selectionEnd = changeLabelGetter.value
-const getDefaultLabel = ({key, before, after}) =>
-  `${key}: ${JSON.stringify(before[key])} -> ${JSON.stringify(after[key])}`
 
-function getChanges({before, after}) {
+const getDefaultLabel = <T>({
+  key,
+  before,
+  after,
+}: {
+  key: keyof T
+  before: T
+  after: T
+}) => `${key}: ${JSON.stringify(before[key])} -> ${JSON.stringify(after[key])}`
+
+function getChanges({before, after}: TestData) {
   const changes = new Set()
-  for (const key of Object.keys(before)) {
-    if (after[key] !== before[key]) {
-      changes.add(
-        (changeLabelGetter[key] ?? getDefaultLabel)({key, before, after}),
-      )
+  if (before && after) {
+    for (const key of Object.keys(before) as Array<keyof typeof before>) {
+      if (after[key] !== before[key]) {
+        changes.add(
+          (key in changeLabelGetter ? changeLabelGetter[key] : getDefaultLabel)(
+            {key, before, after},
+          ),
+        )
+      }
     }
   }
 
diff --git a/src/__tests__/keyboard/index.ts b/src/__tests__/keyboard/index.ts
index 4b573940..3eacd272 100644
--- a/src/__tests__/keyboard/index.ts
+++ b/src/__tests__/keyboard/index.ts
@@ -26,7 +26,7 @@ it('type without focus', () => {
 it('type with focus', () => {
   const {element} = setup('<input/>')
   const {getEventSnapshot} = addListeners(document.body)
-  ;(element as HTMLInputElement).focus()
+  element.focus()
 
   userEvent.keyboard('foo')
 
@@ -53,7 +53,7 @@ it('type with focus', () => {
 it('type asynchronous', async () => {
   const {element} = setup('<input/>')
   const {getEventSnapshot} = addListeners(document.body)
-  ;(element as HTMLInputElement).focus()
+  element.focus()
 
   // eslint-disable-next-line testing-library/no-await-sync-events
   await userEvent.keyboard('foo', {delay: 1})
@@ -110,7 +110,7 @@ describe('error', () => {
 
 it('continue typing with state', () => {
   const {element, getEventSnapshot, clearEventCalls} = setup('<input/>')
-  ;(element as HTMLInputElement).focus()
+  element.focus()
   clearEventCalls()
 
   const state = userEvent.keyboard('[ShiftRight>]')
diff --git a/src/__tests__/keyboard/keyboardImplementation.ts b/src/__tests__/keyboard/keyboardImplementation.ts
index ef3b4f1b..be9d8329 100644
--- a/src/__tests__/keyboard/keyboardImplementation.ts
+++ b/src/__tests__/keyboard/keyboardImplementation.ts
@@ -3,7 +3,7 @@ import {setup} from '../helpers/utils'
 
 test('no character input if `altKey` or `ctrlKey` is pressed', () => {
   const {element, eventWasFired} = setup(`<input/>`)
-  ;(element as HTMLInputElement).focus()
+  element.focus()
 
   userEvent.keyboard('[ControlLeft>]g')
 
diff --git a/src/__tests__/keyboard/plugin/arrow.ts b/src/__tests__/keyboard/plugin/arrow.ts
index 3dea28c1..009744ab 100644
--- a/src/__tests__/keyboard/plugin/arrow.ts
+++ b/src/__tests__/keyboard/plugin/arrow.ts
@@ -2,7 +2,7 @@ import userEvent from 'index'
 import {setup} from '__tests__/helpers/utils'
 
 const setupInput = () =>
-  setup(`<input value="foobar"/>`).element as HTMLInputElement
+  setup<HTMLInputElement>(`<input value="foobar"/>`).element
 
 test('collapse selection to the left', () => {
   const el = setupInput()
diff --git a/src/__tests__/keyboard/plugin/character.ts b/src/__tests__/keyboard/plugin/character.ts
index 424c68f1..c8b6b1f5 100644
--- a/src/__tests__/keyboard/plugin/character.ts
+++ b/src/__tests__/keyboard/plugin/character.ts
@@ -4,10 +4,7 @@ import {setup} from '__tests__/helpers/utils'
 test('type [Enter] in textarea', () => {
   const {element, getEvents} = setup(`<textarea>f</textarea>`)
 
-  userEvent.type(
-    element as HTMLTextAreaElement,
-    'oo[Enter]bar[ShiftLeft>][Enter]baz',
-  )
+  userEvent.type(element, 'oo[Enter]bar[ShiftLeft>][Enter]baz')
 
   expect(element).toHaveValue('foo\nbar\nbaz')
   expect(getEvents('input')[2]).toHaveProperty('inputType', 'insertLineBreak')
@@ -16,12 +13,12 @@ test('type [Enter] in textarea', () => {
 
 test('type [Enter] in contenteditable', () => {
   const {element, getEvents} = setup(`<div contenteditable="true">f</div>`)
-  ;(element as HTMLDivElement).focus()
+  element.focus()
 
   userEvent.keyboard('oo[Enter]bar[ShiftLeft>][Enter]baz')
 
   expect(element).toHaveTextContent('foo bar baz')
-  expect(element?.firstChild).toHaveProperty('nodeValue', 'foo\nbar\nbaz')
+  expect(element.firstChild).toHaveProperty('nodeValue', 'foo\nbar\nbaz')
   expect(getEvents('input')[2]).toHaveProperty('inputType', 'insertParagraph')
   expect(getEvents('input')[6]).toHaveProperty('inputType', 'insertLineBreak')
 })
@@ -36,7 +33,7 @@ test.each([
   'type invalid values into <input type="number"/>',
   (text, expectedValue, expectedCarryValue, expectedInputEvents) => {
     const {element, getEvents} = setup(`<input type="number"/>`)
-    ;(element as HTMLInputElement).focus()
+    element.focus()
 
     const state = userEvent.keyboard(text)
 
diff --git a/src/__tests__/keyboard/plugin/control.ts b/src/__tests__/keyboard/plugin/control.ts
index 224bcf6f..99699fa4 100644
--- a/src/__tests__/keyboard/plugin/control.ts
+++ b/src/__tests__/keyboard/plugin/control.ts
@@ -2,10 +2,12 @@ import userEvent from 'index'
 import {setup} from '__tests__/helpers/utils'
 
 test('press [Home] in textarea', () => {
-  const {element} = setup(`<textarea>foo\nbar\baz</textarea>`)
-  ;(element as HTMLTextAreaElement).setSelectionRange(2, 4)
+  const {element} = setup<HTMLTextAreaElement>(
+    `<textarea>foo\nbar\baz</textarea>`,
+  )
+  element.setSelectionRange(2, 4)
 
-  userEvent.type(element as HTMLTextAreaElement, '[Home]')
+  userEvent.type(element, '[Home]')
 
   expect(element).toHaveProperty('selectionStart', 0)
   expect(element).toHaveProperty('selectionEnd', 0)
@@ -13,22 +15,22 @@ test('press [Home] in textarea', () => {
 
 test('press [Home] in contenteditable', () => {
   const {element} = setup(`<div contenteditable="true">foo\nbar\baz</div>`)
-  document
-    .getSelection()
-    ?.setPosition((element as HTMLDivElement).firstChild, 2)
+  document.getSelection()?.setPosition(element.firstChild, 2)
 
-  userEvent.type(element as HTMLTextAreaElement, '[Home]')
+  userEvent.type(element, '[Home]')
 
   const selection = document.getSelection()
-  expect(selection).toHaveProperty('focusNode', element?.firstChild)
+  expect(selection).toHaveProperty('focusNode', element.firstChild)
   expect(selection).toHaveProperty('focusOffset', 0)
 })
 
 test('press [End] in textarea', () => {
-  const {element} = setup(`<textarea>foo\nbar\baz</textarea>`)
-  ;(element as HTMLTextAreaElement).setSelectionRange(2, 4)
+  const {element} = setup<HTMLTextAreaElement>(
+    `<textarea>foo\nbar\baz</textarea>`,
+  )
+  element.setSelectionRange(2, 4)
 
-  userEvent.type(element as HTMLTextAreaElement, '[End]')
+  userEvent.type(element, '[End]')
 
   expect(element).toHaveProperty('selectionStart', 10)
   expect(element).toHaveProperty('selectionEnd', 10)
@@ -36,14 +38,12 @@ test('press [End] in textarea', () => {
 
 test('press [End] in contenteditable', () => {
   const {element} = setup(`<div contenteditable="true">foo\nbar\baz</div>`)
-  document
-    .getSelection()
-    ?.setPosition((element as HTMLDivElement).firstChild, 2)
+  document.getSelection()?.setPosition(element.firstChild, 2)
 
-  userEvent.type(element as HTMLTextAreaElement, '[End]')
+  userEvent.type(element, '[End]')
 
   const selection = document.getSelection()
-  expect(selection).toHaveProperty('focusNode', element?.firstChild)
+  expect(selection).toHaveProperty('focusNode', element.firstChild)
   expect(selection).toHaveProperty('focusOffset', 10)
 })
 
@@ -51,7 +51,7 @@ test('use [Delete] on number input', () => {
   const {element} = setup(`<input type="number"/>`)
 
   userEvent.type(
-    element as HTMLInputElement,
+    element,
     '1e-5[ArrowLeft][Delete]6[ArrowLeft][ArrowLeft][ArrowLeft][Delete][Delete]',
   )
 
diff --git a/src/__tests__/keyboard/plugin/functional.ts b/src/__tests__/keyboard/plugin/functional.ts
index 51047b26..cc72f8e0 100644
--- a/src/__tests__/keyboard/plugin/functional.ts
+++ b/src/__tests__/keyboard/plugin/functional.ts
@@ -32,7 +32,7 @@ test('produce extra events for the Control key when AltGraph is pressed', () =>
 test('backspace to valid value', () => {
   const {element, getEventSnapshot} = setup(`<input type="number"/>`)
 
-  userEvent.type(element as Element, '5e-[Backspace][Backspace]')
+  userEvent.type(element, '5e-[Backspace][Backspace]')
 
   expect(element).toHaveValue(5)
   expect(getEventSnapshot()).toMatchInlineSnapshot(`
@@ -76,7 +76,7 @@ test('trigger click event on [Enter] keydown on HTMLAnchorElement', () => {
   const {element, getEventSnapshot, getEvents} = setup(
     `<a href="example.com" target="_blank"/>`,
   )
-  ;(element as HTMLAnchorElement).focus()
+  element.focus()
 
   userEvent.keyboard('[Enter]')
 
@@ -99,7 +99,7 @@ test('trigger click event on [Enter] keydown on HTMLAnchorElement', () => {
 
 test('trigger click event on [Enter] keypress on HTMLButtonElement', () => {
   const {element, getEventSnapshot, getEvents} = setup(`<button/>`)
-  ;(element as HTMLButtonElement).focus()
+  element.focus()
 
   userEvent.keyboard('[Enter]')
 
@@ -119,7 +119,7 @@ test('trigger click event on [Enter] keypress on HTMLButtonElement', () => {
 
 test('trigger click event on [Space] keyup on HTMLButtonElement', () => {
   const {element, getEventSnapshot, getEvents} = setup(`<button/>`)
-  ;(element as HTMLButtonElement).focus()
+  element.focus()
 
   userEvent.keyboard('[Space]')
 
@@ -138,8 +138,10 @@ test('trigger click event on [Space] keyup on HTMLButtonElement', () => {
 })
 
 test('trigger click event on [Space] keyup on HTMLInputElement type=button', () => {
-  const {element, getEventSnapshot, getEvents} = setup(`<input type="button" />`)
-  ;(element as HTMLButtonElement).focus()
+  const {element, getEventSnapshot, getEvents} = setup(
+    `<input type="button" />`,
+  )
+  element.focus()
 
   userEvent.keyboard('[Space]')
 
@@ -159,7 +161,7 @@ test('trigger click event on [Space] keyup on HTMLInputElement type=button', ()
 
 test('trigger change event on [Space] keyup on HTMLInputElement type=radio', () => {
   const {element, getEventSnapshot, getEvents} = setup(`<input type="radio" />`)
-  ;(element as HTMLInputElement).focus()
+  element.focus()
 
   userEvent.keyboard('[Space]')
 
diff --git a/src/__tests__/keyboard/shared/fireInputEvent.ts b/src/__tests__/keyboard/shared/fireInputEvent.ts
index 1570f5bb..e5adfac9 100644
--- a/src/__tests__/keyboard/shared/fireInputEvent.ts
+++ b/src/__tests__/keyboard/shared/fireInputEvent.ts
@@ -4,9 +4,9 @@ import userEvent from '../../../'
 it('dispatch change event on blur', () => {
   const {element, getEvents} = setup('<input/>')
 
-  ;(element as HTMLInputElement).focus()
+  element.focus()
   userEvent.keyboard('foo')
-  ;(element as HTMLInputElement).blur()
+  element.blur()
 
   expect(getEvents('change')).toHaveLength(1)
 })
@@ -14,10 +14,10 @@ it('dispatch change event on blur', () => {
 it('do not dispatch change event if value did not change', () => {
   const {element, getEvents} = setup('<input/>')
 
-  ;(element as HTMLInputElement).focus()
+  element.focus()
   userEvent.keyboard('foo')
   userEvent.keyboard('{backspace}{backspace}{backspace}')
-  ;(element as HTMLInputElement).blur()
+  element.blur()
 
   expect(getEvents('change')).toHaveLength(0)
 })
diff --git a/src/__tests__/utils/edit/calculateNewValue.ts b/src/__tests__/utils/edit/calculateNewValue.ts
index 92dc0bdb..79eb4a6b 100644
--- a/src/__tests__/utils/edit/calculateNewValue.ts
+++ b/src/__tests__/utils/edit/calculateNewValue.ts
@@ -5,7 +5,7 @@ import {setup} from '__tests__/helpers/utils'
 
 test('honors maxlength', () => {
   const {element, getEventSnapshot} = setup('<input maxlength="2" />')
-  userEvent.type(element as Element, '123')
+  userEvent.type(element, '123')
 
   // NOTE: no input event when typing "3"
   expect(getEventSnapshot()).toMatchInlineSnapshot(`
@@ -40,7 +40,7 @@ test('honors maxlength', () => {
 
 test('honors maxlength="" as if there was no maxlength', () => {
   const {element, getEventSnapshot} = setup('<input maxlength="" />')
-  userEvent.type(element as Element, '123')
+  userEvent.type(element, '123')
 
   expect(getEventSnapshot()).toMatchInlineSnapshot(`
     Events fired on: input[value="123"]
@@ -77,7 +77,7 @@ test('honors maxlength with existing text', () => {
   const {element, getEventSnapshot} = setup(
     '<input value="12" maxlength="2" />',
   )
-  userEvent.type(element as Element, '3')
+  userEvent.type(element, '3')
 
   // NOTE: no input event when typing "3"
   expect(getEventSnapshot()).toMatchInlineSnapshot(`
@@ -108,7 +108,7 @@ test('honors maxlength on textarea', () => {
     '<textarea maxlength="2">12</textarea>',
   )
 
-  userEvent.type(element as Element, '3')
+  userEvent.type(element, '3')
 
   expect(getEventSnapshot()).toMatchInlineSnapshot(`
     Events fired on: textarea[value="12"]
@@ -137,7 +137,7 @@ test('honors maxlength on textarea', () => {
 test('ignores maxlength on input[type=number]', () => {
   const {element} = setup(`<input maxlength="2" type="number" value="12" />`)
 
-  userEvent.type(element as Element, '3')
+  userEvent.type(element, '3')
 
   expect(element).toHaveValue(123)
 })
diff --git a/src/__tests__/utils/edit/selectionRange.ts b/src/__tests__/utils/edit/selectionRange.ts
index dda87b42..2e6f4315 100644
--- a/src/__tests__/utils/edit/selectionRange.ts
+++ b/src/__tests__/utils/edit/selectionRange.ts
@@ -4,25 +4,25 @@ import {setup} from '__tests__/helpers/utils'
 test('range on input', () => {
   const {element} = setup('<input value="foo"/>')
 
-  expect(getSelectionRange(element as HTMLInputElement)).toEqual({
+  expect(getSelectionRange(element)).toEqual({
     selectionStart: 0,
     selectionEnd: 0,
   })
 
-  setSelectionRange(element as HTMLInputElement, 0, 0)
+  setSelectionRange(element, 0, 0)
 
   expect(element).toHaveProperty('selectionStart', 0)
   expect(element).toHaveProperty('selectionEnd', 0)
-  expect(getSelectionRange(element as HTMLInputElement)).toEqual({
+  expect(getSelectionRange(element)).toEqual({
     selectionStart: 0,
     selectionEnd: 0,
   })
 
-  setSelectionRange(element as HTMLInputElement, 2, 3)
+  setSelectionRange(element, 2, 3)
 
   expect(element).toHaveProperty('selectionStart', 2)
   expect(element).toHaveProperty('selectionEnd', 3)
-  expect(getSelectionRange(element as HTMLInputElement)).toEqual({
+  expect(getSelectionRange(element)).toEqual({
     selectionStart: 2,
     selectionEnd: 3,
   })
@@ -31,25 +31,25 @@ test('range on input', () => {
 test('range on contenteditable', () => {
   const {element} = setup('<div contenteditable="true">foo</div>')
 
-  expect(getSelectionRange(element as HTMLInputElement)).toEqual({
+  expect(getSelectionRange(element)).toEqual({
     selectionStart: null,
     selectionEnd: null,
   })
 
-  setSelectionRange(element as HTMLDivElement, 0, 0)
+  setSelectionRange(element, 0, 0)
 
-  expect(getSelectionRange(element as HTMLInputElement)).toEqual({
+  expect(getSelectionRange(element)).toEqual({
     selectionStart: 0,
     selectionEnd: 0,
   })
 
-  setSelectionRange(element as HTMLDivElement, 2, 3)
+  setSelectionRange(element, 2, 3)
 
-  expect(document.getSelection()?.anchorNode).toBe(element?.firstChild)
-  expect(document.getSelection()?.focusNode).toBe(element?.firstChild)
+  expect(document.getSelection()?.anchorNode).toBe(element.firstChild)
+  expect(document.getSelection()?.focusNode).toBe(element.firstChild)
   expect(document.getSelection()?.anchorOffset).toBe(2)
   expect(document.getSelection()?.focusOffset).toBe(3)
-  expect(getSelectionRange(element as HTMLInputElement)).toEqual({
+  expect(getSelectionRange(element)).toEqual({
     selectionStart: 2,
     selectionEnd: 3,
   })
@@ -58,14 +58,14 @@ test('range on contenteditable', () => {
 test('range on input without selection support', () => {
   const {element} = setup(`<input type="number" value="123"/>`)
 
-  expect(getSelectionRange(element as HTMLInputElement)).toEqual({
+  expect(getSelectionRange(element)).toEqual({
     selectionStart: null,
     selectionEnd: null,
   })
 
-  setSelectionRange(element as HTMLInputElement, 1, 2)
+  setSelectionRange(element, 1, 2)
 
-  expect(getSelectionRange(element as HTMLInputElement)).toEqual({
+  expect(getSelectionRange(element)).toEqual({
     selectionStart: 1,
     selectionEnd: 2,
   })
diff --git a/src/__tests__/utils/misc/hasPointerEvents.ts b/src/__tests__/utils/misc/hasPointerEvents.ts
index d7592683..0b292822 100644
--- a/src/__tests__/utils/misc/hasPointerEvents.ts
+++ b/src/__tests__/utils/misc/hasPointerEvents.ts
@@ -10,8 +10,8 @@ test('get pointer-events from element or ancestor', () => {
         </div>
     `)
 
-  expect(hasPointerEvents(element as HTMLDivElement)).toBe(false)
-  expect(hasPointerEvents((element as HTMLDivElement).children[0])).toBe(true)
-  expect(hasPointerEvents((element as HTMLDivElement).children[1])).toBe(false)
-  expect(hasPointerEvents((element as HTMLDivElement).children[2])).toBe(false)
+  expect(hasPointerEvents(element)).toBe(false)
+  expect(hasPointerEvents(element.children[0])).toBe(true)
+  expect(hasPointerEvents(element.children[1])).toBe(false)
+  expect(hasPointerEvents(element.children[2])).toBe(false)
 })