Is it possible that Typescript does not use type-guard to check for undefined when verifying the truthiness of a variable?

class Base {}

function log(arg: number) {
    console.log(arg);
}

function fn<T extends typeof Base>(
    instance: Partial<InstanceType<T>>,
    key: keyof InstanceType<T>,
) {
    const val = instance[key];
    if (val) {
        log(val);
    }
}

Check out the code in the TS Playground: here

The issue arises when trying to assign 'undefined' to a parameter that expects a 'number.' This can be solved by using the nullish coalescing operator like so: log(val ?? 0).

It may seem surprising that log(val ?? 0) works, as val could potentially be a truthy value that is not a number. However, TypeScript does not throw an error in this scenario.

Answer №1

This issue has been widely recognized. For a deeper understanding of what's happening within the type checker, you can refer to this insightful comment:

The main problem lies in the fact that the narrowed type of fooAnchor is quite complex. The original type is Partial<FooAnchorMap>[keyof TMap], which doesn't simplify neatly into a type that can be definitively assigned to HTMLElement.

Efforts are underway with this ongoing work to address the issue. In the meantime, only temporary solutions exist.

function fn<T extends typeof Base>(
    instance: Partial<InstanceType<T>>,
    key: keyof InstanceType<T>,
) {
    const val: InstanceType<T>[keyof InstanceType<T>] | undefined = instance[key];
    if (val) {
        log(val);
    }
}

Link to playground

You will encounter the following error message:

 Type 'InstanceType<T>[string]' is not assignable to type 'number'.

Answer №2

The undefined concept is a distraction; the issue here is due to the enabled setting of strictNullChecks. This means that unless you specify

function log(arg: number) {
    console.log(arg);
}

as

function log(arg: number | undefined) {
    console.log(arg);
}

you will receive an error whenever passing in anything that could potentially result in undefined. Disabling strictNullChecks would resolve this particular error (while possibly introducing others with the given code); alternatively, ensuring that undefined is handled before being passed in (e.g. ?? 0) can also address it.

I find it interesting that log(val ?? 0) seems to work. If val is a non-numeric truthy value, shouldn't this cause an error since log() expects a number input?

If val ?? 0 does not result in a number and log() requires a number input, it should indeed trigger an error in the scenario where a non-numeric truthy value is supplied. This behavior correctly triggers an error in my experience on the playground. Can you provide an example where it behaves differently?

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

FFmpeg: audio synchronization issue observed with simultaneous usage of xfade and acrossfade techniques

Experiencing an issue when attempting to concatenate 12 videos together and maintain the audio using xfade and acrossfade filters. Without the audio stream, the video encodes correctly, but when combining with audio, transitions hang and audio sync is off. ...

Looking for guidance on where to find a functional code sample or comprehensive tutorial on working with ViewMetadata in Angular2

I am currently trying to understand the relationship between viewmetadata and the fundamental use of encapsulation: ViewEncapsulation, including ViewEncapsulation.Emulated and ViewEncapsulation.None. Here is a link for further information: https://angula ...

Unable to access filteredItems from custom popup in uib-typeahead retrieval process

Issue with Retrieving Filtered Items from ng-repeat in Controller using $scope Despite trying to fetch filtered items from ng-repeat, the value of $scope.filteredItems appears as undefined when I log it to the console. I attempted to implement the solutio ...

When attempting to click on the dropdown in Bootstrap, there is no content displayed

I am currently practicing Bootstrap and focusing on implementing Dropdowns. However, I am facing an issue where upon clicking the Dropdown button, nothing appears on the screen. Preview when it's not clicked Preview when it's clicked Here is m ...

Verify the Ajax submission of a post request prior to transmitting any data

Currently, I am utilizing Google Tag Manager to handle form submission inside a Bootstrap modal. Due to limited backend access, I have opted for GTB to target a specific button and utilize the onClick event. <script> $(document).on('submit&apos ...

Expandable full-width JavaScript accordion for seamless navigation

Currently, I am working on a simple on-page JavaScript application that consists of multiple data pages within one main page. My goal is to create a horizontal accordion effect where clicking on headers on either side will smoothly switch between the diffe ...

Innovative concepts for designing web applications

Here's a unique situation that requires some brainstorming. I'm looking for any advice or suggestions. Imagine a tennis court equipped with sensors throughout - the net, lines, everything has sensors built in. These sensors are constantly sending ...

Swapping React Components with a Click of a Button

My webpage features a button labeled "Sign Up". Once this button is clicked, I want it to display a new component named "SignUp" in place of the original button. Currently, my method involves using setState to trigger the rendering of the new component upo ...

Change the color of the navbar when scrolling using bootstrap and jquery

Using Bootstrap to design a navigation bar, I have two main goals: I want the navbar to change color when the page is scrolled down by 20%, and then revert back to its original color when scrolling back to the top. When the collapse featu ...

Issue: setAllcategories function not found

Currently engaged in using Next.js and Sanity as a Headless CMS for the backend. In the code snippet below, I have created a Categories.js file in the components folder to fetch some data. My objective is to extract all the titles from the category Array. ...

Tips for making jQuery DataTables switch between multiple DOM tables?

I am working on a project where I need to display different jQuery Datatables based on the selected option in a <select> element. The data for each Datatable is stored in hidden DOM <table> elements: <!-- Make sure jquery.dataTables.css and ...

The PKIJS digital signature does not align with the verification process

Explore the code snippet below const data = await Deno.readFile("./README.md"); const certificate = (await loadPEM("./playground/domain.pem"))[0] as Certificate; const privateKey = (await loadPEM("./playground/domain-pk ...

Fetching database entries upon page load instead of using the keyup function in JavaScript

Here is an HTML form input provided: <input type="text" id="username" value=""> In this scenario, when a username like "John" is entered and the enter button is pressed, the script below retrieves database records: $(function(){ //var socket = ...

Ways to add elements to the DOM using jQuery from the local storage?

I'm facing a challenge where I have an input field and store the inputs in local storage. When I click on 'add', I want to immediately append the new inputs to my ul element. However, simply appending the current input won't work as it ...

Incorporating the values of JavaScript objects into a global variable

I'm currently developing a bank account program and facing a challenge in adding my direct debits (DDs) into the global variable. When I create new objects using my constructor function and add them into the bank account, only the last created DD is s ...

Exploring the possibilities of integrating jQuery into Firefox extensions

Can someone provide guidance on effectively implementing jQuery within a Firefox extension? My research has not yielded any up-to-date methods that address the latest version of jQuery, and I am aware that directly including it via script tag may lead to c ...

Unable to delete touchmove event - Vue watching system

Preventing scrolling on mobile devices: const stopScroll = function(e) { e.preventDefault() } Adding the listener: document.body.addEventListener('touchmove', stopScroll, { passive: false }) Removing the listener: document.body.removeEvent ...

Possibility for using navigator.GetUserMedia in Internet Explorer

How can I access a webcam through JavaScript/jQuery? I have successfully opened the webcam in Chrome and Mozilla, but the navigator.GetUserMedia feature does not work in Internet Explorer. Is there a way to achieve this with JavaScript or jQuery in IE? ...

Using PHP to dynamically change the title of a Bootstrap modal

I've been attempting to dynamically update the title of my modal using PHP. The title I wish to display is stored in a variable and is being reassigned based on user input. Below is my PHP code snippet: $studentName = $results['Studentname&apo ...

Executing Javascript requests on a php server hosted on the web

I'm facing a major issue in my application. I have an app that interacts with a PHP webservice and retrieves data upon button press. However, the service is unresponsive, and I'm struggling to identify the root cause. My intention is to send &ap ...