In TypeScript, make sure to verify the type of an object to avoid any potential compilation errors stemming

Here is the code snippet:

export default class App {
  el: HTMLElement;
  constructor(el: string | HTMLElement) {
    if (typeof el === "string") {
      this.el = document.getElementById(el);
    }
    if (typeof el === typeof this.el) {
      this.el = el;
    }
  }
}

If you encounter a compile error message that reads:
Type 'string | HTMLElement' is not assignable to type 'HTMLElement'. Type 'string' is not assignable to type 'HTMLElement'.ts(2322)

You can resolve it by updating the code as follows:

export default class App {
  el: HTMLElement;
  constructor(el: string | HTMLElement) {
    if (typeof el === "string") {
      this.el = document.getElementById(el);
    }
    if (el instanceof HTMLElement) {
      this.el = el;
    }
  }
}

If you're wondering why one version gets an error while the other doesn't, the confusion remains.

Answer №1

The issue is quite evident, the result of typeof el yields one of the types

"string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
during runtime.

During TypeScript compilation, typeof acts as a type guard, narrowing down the type to string | HTMLElement. However, the property this.el in the instance is strictly of type HTMLElement.

To resolve this, you need to refine the type of el to be specifically of type HTMLElement, by verifying that it's not of type string.

instanceof type guards offer a method to restrict types based on their constructor function.

The statement el instanceof HTMLElement will limit the type of el to HTMLElement, which can then be assigned to this.el.

class App {
    el: HTMLElement | null = null;
    constructor(el: string | HTMLElement) {
        if (typeof el === "string") {
            this.el = document.getElementById(el);
        }
        if (typeof el === typeof this.el && typeof el !== 'string') {
            this.el = el;
        }
    }
}

TypeScript Playground

Answer №2

typeof function in JavaScript can return various data types such as undefined, null, boolean, number, bigint, string, symbol, function, and object.

For more detailed information, you can refer to this documentation.

Answer №3

Understanding the distinction between typescript's typeof and javascript's typeof is crucial. As outlined in this documentation, when using typeof in an expression context, it defaults to the behavior of javascript.

if (typeof el === typeof this.el) {
  this.el = el;
}

This comparison essentially checks if both entities share a type of

"string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
. For accurate type inference in typescript, specifying an explicit type in the condition is necessary:

if (typeof el === 'object') {
  this.el = el;
}

In your specific scenario, opting for an else statement would be ideal:

if (typeof el === 'string') {
  this.el = document.getElementById(el);
} else {
  this.el = el;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

React is throwing an error message stating that setCount is not a valid function

Getting an error saying setCount is not a function. I am new to this, please help. import React, { memo, useState } from "react"; export const Container = memo(function Container() { const { count, setCount } = useState(0); return ( ...

What are some ways to style an image that has been added using JavaScript using CSS?

I utilized a JavaScript function to add an image, which looked like this: function show_image(src) { var img = document.createElement("img"); img.src= src; document.body.appendChild(img); } But when I attempt to change its style using CSS: img ...

Populate a bootstrap-select dropdown menu with an array of choices

After creating a table using datatables and adding an empty dropdown select on the footer with Bootstrap-select, here is the code snippet: <tfoot> <tr> <th><select class="selectpicker" multiple></select>< ...

Altering webpage content through the use of Ajax

I need a solution for dynamically updating web page content using JavaScript AJAX. One idea I had was to store different div layouts in separate files, like so: BasicDiv.div: <div> <p>Some Text</p> <button> A Button </ ...

Efficiently organizing reducers into separate files in ReactJS and merging them together

My App is a simple counter app where buttons are images with their own counters. https://i.stack.imgur.com/qkjoi.png In my App.js file, I imported the reducer for the counters using the following code: import reducer from './reducers/reducerCounter&a ...

What is the best way to incorporate a dropdown menu into existing code without causing any disruption?

I've come across this question multiple times before, but I still haven't found a suitable answer or solution that matches my specific situation. (If you know of one, please share the link with me!) My goal is to create a basic dropdown menu wit ...

Adding attributes to parent DOM elements of a component in Angular2: A Step-by-Step Guide

I'm working with the following code: ... <div class="container"> <div class="fancy"> <fancybutton></fancybutton> </div> <button (click)="addAttribute()">Remove</button> <button (click)="remAttr ...

Customize Bootstrap 4 Carousel: Set specific data-interval for each slide

I'm facing an issue with setting the data-interval for each slide of the carousel. I came across a JavaScript code snippet on stackoverflow, but it's not functioning as expected. (Twitter Bootstrap Carousel slide duration) In my HTML, each slide ...

Steps for embedding a custom function in a switch statement

I am attempting to run a switch statement based on the argument provided to the function below. I have been trying to call different functions depending on the argument passed. However, I encountered an Uncaught ReferenceError in the beginning of the .js f ...

A Node.js feature that enables atomic file replacement, triggering watchers only once

I have a unique scenario where I need to handle two types of processes. One process is responsible for writing a file, while the other processes are required to read it whenever there is a change. In my research, I came across fs.watch as a solution to ke ...

Using Ajax to implement a content slider with lightSlider

Seeking assistance in developing a dynamic content slider utilizing the LightSlider plugin. Currently, I have a script that fetches content from a database table (outputting JSON to HTML) and displays 6 div's of content per slide. However, I aim to di ...

Is there a way to apply a consistent style to all the fields of an object at once?

I have a formatting object named typography that includes various styles. One common issue I've encountered is that the line-height property is consistently set to 135%. Anticipating that this might change in the future, I am looking for a way to cent ...

Somehow, my array only manages to traverse exactly half of its elements

Something odd is happening with my input tag in the HTML file where only half of my array elements are being processed. The input collects numbers/letters and assigns a line of code, like this: let result = Object.fromEntries( Object.entries(answers2).m ...

Typescript encounters Duplicate error when method overloading is implemented

Below is the code snippet that I am working with: public async insert(data: iFlower | iFlower[]): Promise<iFlower> | Promise<iFlower[]> { await this.insert(data); } private async insert(data: iFlower): Promise<iFlower>{ .... return d ...

Using setTimeout to click and hold on an element in Javascript

I am in need of adding a feature to my web app where a specific action is triggered when the user clicks and holds on an element, similar to the long press on Android. Here is the HTML code for my div: <div id="myDiv" onmousedown="press()" onmouse ...

Tips for assessing the prop that is being passed to a styled component with React and TypeScript

I am trying to apply a background color to a styled component div only if the state "active" is true. This is how I am currently attempting to do it: function Main() { const [active, setActive] = useState(false); return ( <ChildCompone ...

Disabling the .hover function temporarily

I am currently exploring how to temporarily disable the .hover function in jQuery based on a specific event that occurs on the page. You can view my current jsfiddle here: http://jsfiddle.net/4vhajam3/3/ (please note that I have omitted some code for simp ...

Combining Angular 2 and Sails.js for Ultimate Web Development

Looking to integrate Sails with Angular 2 and add TypeScript to my project. As a newcomer in this field, I'm unsure how to configure this. I have created a Sails app using the command: sails new myApp Could anyone guide me on how to incorporate thi ...

Ways to change attributes of deeply embedded objects?

Imagine having a complex object with nested properties like this: const obj = { Visualization: { Lower: [{ name: "Part", selectedValue: "60-000" }], Upper: [{ name: "Part", selectedValue: "60-000" }], ...

How to properly adjust HTTP headers within an AngularJS factory

Looking for guidance from an Angular expert. I want to know how to modify the header for POST in the code snippet below: 'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'? The provided code is as follows: var tableMod ...