Exploring the keyof operator in Typescript for object types

Is there a way to extract keys of type A and transfer them to type B?
Even though I anticipate type B to be "x", it seems to also include "undefined".
Why does the keyof operator incorporate undefined in the resulting type? It's perplexing.
I know I can use the Required utility as a workaround, but I'm curious about the inner workings of the keyof operator because the documentation doesn't offer much insight.

playground

type A = {x?: string | null};
type B = {[Key in keyof A]: Key}[keyof A];

Answer №1

A type that is homomorphic mapped (explained in this What does "homomorphic mapped type" mean?) takes the shape of {[K in keyof T]: ⋯T[K]⋯}, keeping intact the optional and/or readonly characteristics of the mapped properties. Optional property goes in, optional property comes out:

type A = { x?: string | null };
//   ^? { x?: string | null | undefined }

type B0 = { [Key in keyof A]: Key };
//   ^? { x?: "x" | undefined }

Furthermore, optional properties inherently encompass undefined within their scope. When you inspect the type using IntelliSense, you will typically see | undefined included, as visible in the example above. (Assuming --strictNullChecks is enabled but not the --exactOptionalPropertyTypes compiler option.)

Consequently, when you access it to extract values as a union, any optional property results in adding an undefined to the union:

type B = B0[keyof A];
//   ^? "x" | undefined

Hence, the presence of | undefined isn't due to keyof specifically, but rather from the | undefined linked to the type being mapped.


As indicated, you have the option to utilize Required or the -? mapping modifier to resolve this issue:

type B = { [K in keyof A]-?: K }[keyof A];
// type B = "x"

Check out the code on the TypeScript Playground link

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

Can JavaScript be used to dynamically update drop down lists in a gridview?

My gridview has multiple fields including PreviousPoints, GainedPoints, and TotalPoints. In edit mode, PreviousPoints is not editable, GainedPoints is a dropdown list, and TotalPoints is also a dropdown list. Whenever the selected value in GainedPoints ch ...

Retrieve the Checked Value of a Checkbox Using Ajax Post in MVC

Can anyone provide assistance? This is the code I am working with: Index.cshtml <!DOCTYPE html> <html> <head> <title>jQuery With Example</title> @Scripts.Render("~/bundles/jquery") <script type="text/javascri ...

How to Retrieve Information from an Array in VueJS

At the moment, the data being displayed on my page is an array, as shown in the snippet below: https://i.stack.imgur.com/zAvrc.png However, I only want to retrieve or display the project names. This is all I have at the moment: fetch(context,id){ ...

The custom confirmation popup is experiencing technical issues

Currently, I am utilizing a plugin to modify the appearance of the confirm popup. Although I have successfully customized the confirm popup, I am encountering an issue where upon clicking the delete icon, the custom confirm popup appears momentarily before ...

What is the best way to extract individual words from a string based on a specified list of tokens?

I am currently working with a list of tokens used to create artificial Japanese words, which is represented by the following array: var syllables = ["chi","tsu","shi","ka","ki","ku","ke","ko","ta","te","to","sa","su","se","so","na","ni","nu","ne","no","ha ...

Combining HashRouter and anchor navigation in React: A guide to seamless page navigation

I am currently utilizing the HashRouter functionality from the library react-router-dom. The issue I am facing is when attempting to link to a specific div on the same page using an anchor tag: <a href="#div-id"> Link to div </a> In ...

`I'm encountering issues when trying to pass an array through localStorage into a new array`

This is a complex and detailed question that I am struggling to find a solution for. Despite using deprecated mysql due to hosting limitations, the problem lies elsewhere. Part 1 involves dataLoader.php, which queries the database and retrieves posx and p ...

When I refresh the page in Angular2, the router parameters do not get loaded again

When loading my application on routers without parameters, everything is normal. However, when trying to use a router with params, the application fails to load. For example: localhost:3000/usersid/:id The code for the router is as follows: const appRou ...

What is the best way to align a box once another one has been placed?

I have integrated both Bootstrap and Masonry plugins into my website design. The issue I am facing is that the Masonry plugin box goes under the top Bootstrap bar. I tried adding a margin-top: 50, but this resulted in a horizontal scroll bar appearing. To ...

Increasing the upward motion of the matrix raining HTML canvas animation

Recently, I've been experimenting with the Matrix raining canvas animation here and I was intrigued by the idea of making it rain upwards instead of downwards. However, my attempts to achieve this using the rotate() method resulted in skewing and stre ...

The ng-view directive within AngularJS appears to be malfunctioning

I am facing an issue with my simple Angular app. I have two links that are supposed to change the URL and display the correct view within the same single page application. However, when I include the controllers' module in the main module, it stops wo ...

What is the reason behind TS not using Symbols for enums?

When it comes to enums, ES6 symbols provide a great solution for avoiding collisions. Initially, I assumed that TypeScript's enum type used Symbols for enums if the target was set to 'es6', but it turns out it doesn't: enum Role {Emplo ...

Absence of property persists despite the use of null coalescing and optional chaining

Having some trouble with a piece of code that utilizes optional chaining and null coalescing. Despite this, I am confused as to why it is still flagging an error about the property not existing. See image below for more details: The error message display ...

Why is it that I am unable to properly encode this URL in node.js?

$node querystring = require('querystring') var dict = { 'q': 'what\'s up' }; var url = 'http://google.com/?q=' + querystring.stringify(dict); url = encodeURIComponent(url); console.log(url); Here is the re ...

Adjust ChartJS yAxes "tick marks"

I'm having trouble adjusting the scales on my yAxes and all the information I find seems to be outdated. My goal is to set my yAxes range from 0 to 100 with steps of 25. Check out this link yAxes: [ { ...

Indicate the type of content returned by a Controller

I'm dealing with a metrics.controller.ts file that looks like this: import { Controller, Get } from '@nestjs/common'; import { ApiOperation, ApiResponse, ApiUseTags, ApiModelProperty } from '@nestjs/swagger'; import { PrometheusSe ...

Is there a way to retrieve the name of a JSON or obtain the file path using NodeJS Express Router?

I've been experimenting with adding a named routers feature to the Express router for my NodeJS project. I managed to implement it successfully, but there's one thing I'm stuck on... the path. Specifically, when I have a route setup like thi ...

Verify the input in text fields and checkboxes using JavaScript

I'm in the process of creating a complete "validate-form" function, but there are still a couple of things missing: Ensuring that the Name field only allows alphabetical characters and white spaces Validating that at least one checkbox is selected, ...

Having trouble navigating the Request and Response handling in Expressjs/Nodejs?

As I continue to delve deeper into this code, confusion seems to cloud my understanding. Here is the provided source: var express = require('express') , http = require('http') , server = express() ; var home = require('./ro ...

Troubleshooting error in WordPress: Changing innerHTML of dynamically created divs using JavaScript. Issue: 'Unable to set property innerHTMl of null'

I am struggling to modify the innerHTML of a "View cart" button using a dynamically generated div class on my Wordpress/Woocommerce site. In a previous inquiry, I was informed (thanks to Mike :) ) that since JavaScript is an onload event, the class changes ...