What is the reason that TypeScript's type guarding with 'in' does not narrow types to keyof types?

Here's some code to consider:

const obj = {
    a: 1,
    b: 2
}

let possibleKey: string = 'a'

if (possibleKey in obj) console.log(obj[possibleKey])

When possibleKey in obj evaluates to true, shouldn't we expect possibleKey to have the type keyof typeof obj? Why doesn't TypeScript automatically narrow down the type of string to that specific type? Instead, it throws the error message:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ a: number; b: number; }'.

Answer №1

According to information taken from the official documentation:

When using the expression n in x, where n is a string literal or string literal type and x is a union type, the "true" branch narrows down to types that have an optional or required property named n, while the "false" branch narrows down to types that have either an optional or missing property named n.

In simpler terms, n in x affects the narrowing of x, not n, and exclusively for string literals or string literal types within union types. To make this expression work correctly, additional information needs to be provided to the compiler, such as through a type assertion:

if (possibleKey in obj) {
  console.log(obj[<keyof typeof obj>possibleKey]);
}

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

The attribute 'ref' is not found in the type 'IntrinsicAttributes & PhoneInputProps & { children?: ReactNode; }'

I keep receiving the following error message: Property 'ref' does not exist on type 'IntrinsicAttributes & PhoneInputProps & { children?: ReactNode; }'. How can I resolve this issue? import React, {ForwardedRef} from 'react ...

Typescript React Union type

I have developed a Card component with two different variants: Wrapper and Dashboard. Each variant comes with its own set of props. export type DashboardProps = { variant: CardVariant.Dashboard, primaryText: string, secondaryText: string, icon: Ove ...

When using the listServiceLevelObjectives function, an UnhandledPromiseRejectionWarning occurs: The error message returned is "3 INVALID_ARGUMENT

Hey there, I'm struggling to retrieve a list of SLOs in my Google Cloud project via the REST API using TypeScript. Unfortunately, I keep running into an error message. Could you lend me a hand with this? The error reads: (node:47173) UnhandledPromis ...

What steps do I need to follow to create a unique angular component that allows for customizable width using CSS styles?

The instructions on this website suggest that the width of the side-nav can be changed using CSS like so: md-sidenav { width: 200px; } This leads me to wonder, can I apply standard CSS properties such as width, position, etc... to custom components wi ...

Troubleshooting TypeScript window augmentation not functioning in individual modules

I would like to extend the window object with a new property. This can be achieved by adding the following code: // global.d.ts import { IConfig } from './src/models'; export {}; declare global { interface Window { _env: IConfig; ...

I'm looking to integrate language switching into my Angular application with the help of the official Angular i18n library. How can I

In order to enable language switching in my Angular application, I am looking to utilize the official Angular i18n library. This decision comes as a result of the previous go-to library (ngx-translate) being put into maintenance mode and scheduled for depr ...

Disabling a Field in Angular While Preserving its Value

Hey there, late night folks! I have a quick question about Angular. I'm working with a form that includes a specific field where I set the value using patchValue, but I also need to disable this field. The issue is that after disabling it, the value i ...

Reorganize the data in a different manner (collections of items instead of individual items linked to groups)

Is there a way to create a function that converts data from `DevicesType` to `GroupsType` below? Instead of having a list of devices showing the groups they belong to, I need a list of groups with their respective devices. type DevicesType = { id: string ...

Is it necessary to use useCallback when executing a function from a child component?

Consideration should be given to using useCallback when ensuring referential equality during parent component renders. However, it's unclear if this is necessary in a scenario where the parent is dealing with a child function. import { ReactNode, useC ...

Running Protractor in Components: A Comprehensive Guide

Protractor is commonly known as a testing framework, and I am currently utilizing Angular 2 for my application. I am interested in incorporating it into my app components, such as launching a browser when a button is clicked. Could you provide guidance o ...

Changing the background color dynamically with NextJS and TailwindCSS based on a specific value

I'm currently working with a table that fetches values from an API. My goal is to dynamically change the background color of the Status Field based on the value received for request.status There are a total of 4 status values: Completed Work in Prog ...

Troubleshooting Issues with Imports after Integrating Typescript into Vue and Rails Application

I attempted to integrate TypeScript into my existing VueJS + Rails application. I started by cloning a demo from (https://github.com/gbarillot/rails-vue-demo-app) and then following the guidelines provided on https://github.com/rails/webpacker $ bundle ex ...

Tips for implementing multiple Angular components within a loop

I am currently working on a pop-up notification system for displaying all unrated purchase order deliveries. However, I am facing a challenge in implementing *ngFor loop to iterate through the orders. My system allows users to rate their item order delive ...

Threejs BufferGeometry Index Update (faces added)

I have successfully added vertices to a BufferGeometry and updated the positions attribute, but now I am struggling with adding faces (updating the index). Does anyone know how to accomplish this task effectively? const vertices = new Float32Array(100 * 3) ...

Tips for sending an array containing objects with an ID using Angular

Can you give me your thoughts on how to post an array with some object? This is the code I am working with: const selectedJobs = this.ms.selectedItems; if (!selectedJobs) { return; } const selectedJobsId = selectedJobs.map((jobsId) => ...

Troubleshooting type conflicts while utilizing the 'withRouter' function in Typescript

Currently, I am delving deeper into React and TypeScript, seeking to expand my understanding and practical experience. While utilizing withRouter from react-router-dom, I encountered a typing error. The issue arose within my simplistic code snippet. I att ...

Executing multiple instances of the cascading dropdown fill method in Angular 7

I am currently working on an Angular app that includes cascading comboboxes for country and state selection. However, I have noticed that the get states() method in my state.component.ts file is taking a long time to run. What could be causing this issue? ...

Angular template driven forms fail to bind to model data

In an attempt to connect the model in angular template-driven forms, I have created a model class and utilized it to fill the input field. HTML: <div class="form-group col-md-2 col-12" [class.text-danger]="nameCode.invalid && nameCode.touched ...

sort the array based on its data type

Recently diving into typescript... I have an array that is a union of typeA[] | typeB[] but I am looking to filter based on the object's type interface TypeA { attribute1: string attribute2: string } interface TypeB { attribute3: string attri ...

Issue with Material UI: Unable to utilize import statement outside of a module due to Select dependency

Hello there! Here is my query: I am currently working on a project using NextJS + React with node. Everything seems to be running smoothly, except for one issue I encounter when reloading a page with a Select component from Material UI. The relevant code ...