Separate the generic function interface into its own type/interface variable

Below is an example of TypeScript generics that I found on typescriptlang.

function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
  return obj[key];
}

let x = { a: 1, b: 2, c: 3, d: 4 };

getProperty(x, "a");
getProperty(x, "m");

I wanted to extract the generic type to a variable for reuse. However, my attempt resulted in an error:

type MyType<Type, Key extends keyof Type> = {obj: Type, key: Key}

let x = { a: 1, b: 2, c: 3, d: 4 };


function getPropertyGeneric(params: MyType<x>) {
  return obj[key];
}

The error message reads:

Generic type 'MyType' requires 2 type argument(s).

Playground

Answer №1

When defining the following type:

type MyType<Type, Key extends keyof Type> = {obj: Type, key: Key}

You are required to explicitly provide 2 type parameters like so:

function getPropertyGeneric(params: MyType<typeof x, keyof typeof x>) {
  return params.obj[params.key];
}

Link to playground

However, you can utilize generic parameter default for the second type parameter by defining MyType as:

type MyType<Type, Key extends keyof Type = keyof Type> = {obj: Type, key: Key}

This allows you to either provide or omit the second type parameter:

function getPropertyGeneric2(params: MyType<typeof x, keyof typeof x>) { // no error
  return params.obj[params.key];
}

function getPropertyGeneric1(params: MyType<typeof x>) { // no error
  return params.obj[params.key];
}

Link to playground

It's important to note that using the value x in a type context is not allowed. You must instead retrieve its type using the typeof operator.

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 failure to build was due to the absence of the export of ParsedQs from express-serve-static-core

Encountered the error message [@types/express]-Type 'P' is not assignable to type 'ParamsArray'. Resolved it by installing specific packages "@types/express": "^4.17.8", "@types/express-serve-static-core": ...

I'm experiencing a strange issue where my component's values remain unchanged even after re-rendering the component with new values. I wonder if this could be a result of Next.js caching

Perhaps the title didn't fully capture what I'm trying to explain, so here's a breakdown. I'm in the process of developing a habit tracker. This tracker enables users to create their own habits which are stored in a habits mongodb tabl ...

Tips for utilizing jest.mock following the removal of @types/jest (^jest@24)

After upgrading from version 7 to version 8 of @angular-builders/jest, I followed the instructions provided in the migration guide which advised removing @types/jest since it now comes bundled with Jest v24. Additionally, changes were made to my tsconfig a ...

Having trouble uploading images using Ionic/Angular to a PHP script

I've been working on incorporating image uploading functionality into my Ionic app. Despite reading multiple tutorials, I haven't been able to get it up and running successfully. I'm specifically aiming for the app to work smoothly in a web ...

In Typescript 12, the process of creating a Bootstrap popup that waits for the user to click on a value entered in

Greetings! I am currently working with Angular TypeScript 12 and I am attempting to trigger a Bootstrap modal popup when I enter a code in the input field and press enter. However, the issue is that the popup is always displayed even without typing anythin ...

What is the reason for an optional object property being assigned the 'never' type?

I'm having trouble understanding the code snippet below: interface Example { first?: number, second?: { num: number } } const example: Example = { first: 1, second: { num: 2 } } function retrieveValue<Object, Key exte ...

In just a single line of code, you can iterate through a Record object and retrieve an array of DOM elements

I am working with an object type MyType = 'name' | 'base' | 'six'; obj: MyType = { 'name': {key: 'm1'}, 'base': {key: 'm2'}, 'six': {key: 'm3'}, } My goal is ...

How do I verify if a boolean variable has been changed within an Angular service?

In my MatHorizontalStepper parent component, I utilize the subscribe function to monitor changes in an Observable within a service. The purpose is to automatically progress to the next step in the stepper when the observable switches from false to true. D ...

Retrieving a global variable within a nested function

I am encountering a scope issue with my nested function while trying to pass two global variables. I need some help as I keep getting this error when running the code: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'use ...

Show a dropdown menu based on a certain condition in Angular

Is there a way to conditionally display select options like this? <select id="updateType" class="form-control" formControlName="updateType"> <option value="personalDetails">Personal</option> <option value="addressD ...

Creating a JSON file using an object to send requests in Angular

In my Angular 7 project, I am trying to send a multipart request to the server that includes a file (document_example.pdf) and a json file containing a data object (data_object_example.json). The content of data_object_example.json is as follows: { " ...

Error: Unexpected top-level property "import/order" in ESLINT configuration

I'm in the process of setting up a guideline to include one blank line between internal and external imports. .eslintrc.json: { "parser": "@typescript-eslint/parser", "env": { "es6": true, " ...

Issue: The module '@nx/nx-linux-x64-gnu' is not found and cannot be located

I'm encountering issues when trying to run the build of my Angular project with NX in GitHub Actions CI. The process fails and displays errors like: npm ERR! code 1 npm ERR! path /runner/_work/myapp/node_modules/nx npm ERR! command failed npm ERR! c ...

Evolving fashion trends

I'm looking to dynamically change the style of my HTML element based on screen size, similar to this example: <p [ngStyle]="{'color': isMobile() ? 'red' : 'blue'}">Lorem Ipsum</p> The code above triggers a m ...

PlatypusTS: Embracing Inner Modules

Incorporating angular, I have the capability to fetch object instances or import modules using the $injector in this manner: export class BaseService { protected $http: angular.IHttpService; protected _injector: angular.auto.IInjec ...

When a checkbox is clicked, how can we use Angular 4 to automatically mark all preceding checkboxes as checked?

I have a series of checkboxes with labels such as (Beginner, Intermediate, Advanced, Expert, etc.). When I click on any checkbox, I want all previous checkboxes to be checked. For example: If I click on Advanced, only the preceding checkboxes should get ...

Issue with border radius in MUI 5 affecting table body and footer elements

Currently, I am diving into a new project utilizing React version 18.2 and MUI 5.10.3 library. My main task involves designing a table with specific styles within one of the components. The table header should not display any border lines. The table body ...

What methods can be used to monitor changes made to thumbnails on the YouTube platform?

I have embarked on a project to create a Chrome extension that alters the information displayed on the thumbnails of YouTube's recommended videos. In this case, I am looking to replace the video length with the name of the channel. Imagine you are on ...

Using @carbon/react in conjunction with Next.js version 13 leads to unconventional styling

Here's what I did to set up my Next.js application: npx create-next-app@latest I then installed the necessary package using: npm i -S @carbon/react The global styles in app/globals.scss were customized with this code snippet: @use '@carbon/reac ...

What is the best way to utilize a reduce function to eliminate the need for looping through an object in JavaScript?

Currently, my code looks like this: const weekdays = eachDay.map((day) => format(day, 'EEE')); let ret = { Su: '', Mo: '', Tu: '', We: '', Th: '', Fr: '', Sa: '' }; w ...