Is it possible to specify broad keys of a defined object in TypeScript using TypeScript's typing system?

const obj: {[key: string]: string} = {foo: 'x', bar: 'y'};

type ObjType = keyof typeof obj;

Is there a way to restrict ObjType to only accept values "foo" or "bar" without changing the type of obj?

Answer №1

It is currently not possible to achieve this in typescript 4.8. You are unable to restrict a type and then use a more specific version of that type in the same assignment.

The common workaround is to utilize a generic function, although it is not ideal.

function createObject<T extends { [key: string]: string }>(obj: T) {
    return obj
}

const newObj = createObject({foo: 'x', bar: 'y'})

type NewObjType = keyof typeof newObj // 'foo' | 'bar'

View playground


However, it appears that the upcoming version of typescript (4.9) may introduce the satisfies operator. More information can be found on this github issue

This new feature will allow you to enforce a constraint and infer the more specific type simultaneously.

const newObj = {foo: 'x', bar: 'y'} satisfies { [key: string]: string }

type NewObjType = keyof typeof newObj // 'foo' | 'bar'

View playground


Regardless, changes to how newObj is declared will be necessary for any of these approaches to work.

Answer №2

Allow the inference to handle it:

const object = {name: 'Alice', age: 30};

type ObjectType = keyof typeof object; //  "name" | "age"

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

Creating an RxJS observable stream from an event emitted by a child element in an Angular 2 component template

Currently incorporating Angular 2.0.0-rc.4 alongside RxJS 5.0.0-beta.6. In the midst of exploring various methods for generating observable streams from events, I find myself inundated with choices and would like to gather opinions. Recognizing that there ...

Exploring Typescript: Uncovering the Secrets of the navigator.connection Property

I am trying to access the NetworkInformation interface by using a simple TypeScript function like the one shown below: private checkNetworkConnection(): void { const connection = Navigator.connection || navigator.mozConnection || navigator.webkitConn ...

Trouble with updating a variable within a loop in Cypress

During my experience with writing Cypress tests, I came across an issue that is preventing me from updating a specific variable. The goal of my test is to run a loop and update the questionId variable within each iteration for making API queries. However, ...

What is the best method to terminate an Electron application using TypeScript?

I have been searching for the proper method to close an Electron app. My app uses React and TypeScript. After coming across this helpful post, I discovered a working solution: const remote = require('electron').remote; let w = remote.getCurrentW ...

Webpack 2.7.0 throws an error: "Unexpected parameter: theme"

At the moment, I am on webpack 1.16.0 and using --theme as an argument to set the output path and plugin paths. The command appears as: rimraf dist && webpack --bail --progress --profile --theme=<name of theme> However, as I try to upgrade ...

PhpStorm IDE does not recognize Cypress custom commands, although they function properly in the test runner

Utilizing JavaScript files within our Cypress testing is a common practice. Within the commands.js file, I have developed a custom command: Cypress.Commands.add('selectDropdown', (dropdown) => { cy.get('#' + dropdown).click(); } ...

ESLint warning: Potentially risky assignment of an undetermined data type and hazardous invocation of an undetermined data type value

Review this test code: import { isHtmlLinkDescriptor } from '@remix-run/react/links' import invariant from 'tiny-invariant' import { links } from '~/root' it('should return a rel=stylesheet', () => { const resp ...

Is there a way to adjust the height of mat-sidenav-content to be 100%?

I'm having trouble scrolling down my mat-sidenav-content to reach the bottom where my pagination is located. When I try using fullscreen on mat-sidenav-container, my mat-toolbar disappears. How can I adjust my mat-sidenav-content based on the content? ...

Angular 2 encountering an error with the HTTP GET request

I am currently facing some challenges with subscribing to the response while using the http method get request. Below is my service implementation: import { Injectable } from '@angular/core'; import { Http, Response } from '@angular/http&ap ...

Error message: "ReferenceError occurred while trying to access the Data Service in

As I embark on the journey of creating my very first MEAN stack application - an online cookbook, I have encountered a challenge in Angular. It seems like there is an issue between the service responsible for fetching recipe data from the API (RecipeDataSe ...

Remove an element from an array within objects

Need help with removing specific items from an array within objects? If you want to delete all hobbies related to dancing, you may consider using the splice method const people = [{ id: 1, documents: [{ ...

Unable to add chosen elements to array - Angular material mat select allowing multiple selections

Can anyone assist me in figuring out what I am doing wrong when attempting to push data to an empty array? I am trying to only add selected values (i.e. those with checked as true), but I can't seem to get inside the loop This is the current conditi ...

Using Typescript to retrieve the Return Type of a function when called with specific Parameter types

My goal is to create 2 interfaces for accessing the database: dao can be used by both admins and regular users, so each function needs an isAdmin:boolean parameter (e.g. updateUser(isAdmin: boolean, returnUser)) daoAsAdmin, on the other hand, allows metho ...

Avoid triggering the onClick event on specific elements in React by utilizing event delegation or conditional rendering

programming environment react.js typescript next.js How can I prevent the onClick process from being triggered when the span tag is pressed? What is the best approach? return ( <div className="padding-16 flex gap-5 flex-container" ...

Access values of keys in an array of objects using TypeScript during array initialization

In my TypeScript code, I am initializing an array of objects. I need to retrieve the id parameter of a specific object that I am initializing. vacancies: Array<Vacancy> = [{ id: 1, is_fav: this.favouritesService.favourites.find(fav = ...

Unable to loop through the "dataList" retrieved from a service call to the java backend within an Angular 9 application

After receiving JSON data from a Java backend service called houseguidelines, the information is sent to an Angular application via a service call. I am attempting to iterate over this returned JSON data and add it to an array I have created. Unfortunately ...

NestJS does not recognize TypeORM .env configuration in production build

Currently, I am developing a NestJS application that interacts with a postgres database using TypeORM. During the development phase (npm run start:debug), everything functions perfectly. However, when I proceed to build the application with npm run build a ...

Unable to locate module in node_modules directory when attempting to import an image into TS

In my .tsx file, I am encountering an issue with the following code snippet: import L from 'leaflet'; import icon from 'leaflet/dist/images/marker-icon.png'; import iconShadow from 'leaflet/dist/images/marker-shadow.png'; The ...

What is the best way to categorize variables?

How can I organize variables together: export let findbyc$: Observable<Object>; export let findbyi$: Observable<Object>; export let findbyo$: Observable<Object>; export let findbyob$: Observable<Object>; I would like to group them ...

Retrieve JSON data within a service and provide it to a component

I am currently facing an issue with loading data from a JSON file into my component using a service. The data is successfully loaded in the service, as confirmed by the console log; however, when trying to access the data in the component, it does not disp ...