TS2322: Type 'HTMLElement | null' is not assignable to type 'HTMLButtonElement'. and other errors when enabling button on pressing terms checkbox

Viewed 126

I would like to enable/ disable a button when someone presses the terms checkbox and I created the following function:

const enableButton = (checkBox: HTMLInputElement ) => {
    var submitButton = document.getElementById("submit_button");
    var isChecked = checkBox.checked;

    if(isChecked) {
        submitButton!.disabled == false;
    } else {
        submitButton!.disabled == true;
    }
}

I am doing it with React and TypeScript. When I change it to the following, I get the error that you can see in the description. In general I think I am missing something with assigning types etc. Whatever I do, when I fix something I get different errors.

var submitButton: HTMLButtonElement = document.getElementById("submit_button");
1 Answers

Document.getElementById(elementId: string): HTMLElement | null by the default returns HTMLElement | null

HTMLButtonElement is more specific type.

Since, getElementById just can't know what type of element are you looking for it just returns more general type.

In order to handle this, you should create your custom typeguard. Since somebody always can change your HTML.

import React from 'react'

const hasProperty = <
  Obj,
  Prop extends string
>(obj: Obj, prop: Prop)
  : obj is Obj & Record<Prop, unknown> =>
  Object.prototype.hasOwnProperty.call(obj, prop);


const isButton = (element: HTMLElement | null):
  element is HTMLButtonElement =>
  Boolean(element) && hasProperty(element, 'disbaled')

const enableButton = (checkBox: HTMLInputElement) => {
  var submitButton = document.getElementById("submit_button");
  var isChecked = checkBox.checked;

  if (isButton(submitButton)) {
    if (isChecked) {
      // don't need to use exclamation mark
      submitButton.disabled == false;
    } else {
      submitButton.disabled == true;
    }
  }
}

Playground

Related