Beginner in Typescript - Exploring ways to verify an interface using an index

When working with a list of operations in a database, each operation may have a unique set of variables that need to be passed. To make adding new operations easier, I decided to store the interfaces within a list structure like this:

const operation = {
    add: 'example',
    list: 'example2',
};
interface operationVariable {
    add: { asset: string };
}

The goal is to access the correct interface for each operation from the list using a function like this:

function graphql<OP = keyof typeof operation>(request: OP, variables: operationVariable[OP], server = CONFIG.GRAPHQLSERVER) {
    return post(server, request);
}

However, an error message stating:

Type 'OP' cannot be used to index type 'operationVariable'.

Even if the 'list' operation is removed, the error persists. How can TypeScript be configured to behave according to my intentions?

Answer â„–1

Inform TypeScript that operation is a collection of keys from operationVariable paired with strings:

const operation: Record<keyof operationVariable, string> = {
    add: 'example',
    list: 'example2', // error, not in operationVariable
};

The key aspect you overlooked is the use of extends. By incorporating the extends keyword, you apply a generic constraint to signify to TypeScript that this type must be a subtype of another:

function graphql<
    OP extends keyof typeof operation
//     ^^^^^^^ OP is a keyof typeof operation
>(request: OP, variables: operationVariable[OP], // works

For further clarification, refer to the explanation provided in thehandbook.

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

Converting API data to an array map in React with Typescript

There is an array data retrieved from an API that needs to be rendered in a React TypeScript file using the map function. { "data":{ "cart":{ "1":{ "product_id":1, "name":"Product 1", "quantity":1, ...

Error message: Duplicate identifier found in Typescript

Encountering an error while trying to run my angular-meteor client (ionic serve), specifically: [00:29:20] typescript: node_modules/meteor-typings/1.3/main.d.ts, line: 657 Duplicate identifier 'Status'. L657: type Status ...

Learn to extract metadata from a gRPC service function using Node.js

Currently, my gRPC service is up and running with the following setup: server.addService(PassportService, implementation); server.bind(mfeConfig().grpc.passport, grpc.ServerCredentials.createInsecure()); server.start(); To call this service from a client ...

What steps should be taken to properly utilize the useRef hooks in this code snippet?

I've been working on a beer wishlist project using React. However, I encountered an issue with the following error message: TS2786: 'EditBeerPage' cannot be used as a JSX component. Its return type 'Element | undefined' is not a ...

To switch to desktop mode, double click; for mobile view, just tap once

I am looking to implement 2 different gestures for a specific feature in my application. Ideally, I want users to be able to double click on a card to open it in desktop view, but if they are using a phone, a single tap should suffice. How can I achieve th ...

Accessing data from Firebase Database Object

I am currently facing a challenge in extracting a username value from my firebase database and then displaying it in a console log statement. The issue lies in fetching the child value instead of just the object. How can I retrieve the child value and prin ...

Tips for retrieving a cropped image with Croppr.js

Currently, I am developing a mobile application using Ionic 3. Within the application, I have integrated the Croppr.js library to enable image cropping before uploading it to the server. However, I am facing an issue where I am unable to retrieve the cropp ...

Unusual conduct observed during the conversion process from TypeScript to JavaScript

I'm currently in the process of transitioning my NodeJs app from JavaScript to TypeScript to take advantage of its various benefits. However, I seem to be encountering issues with even the simplest tasks. In my index.ts file, I have the following bas ...

Tips on ensuring a certain HTML tag is used in the component interface

I developed a custom checkbox component that can receive children props from its parent interface CustomCheckboxProps { children?: string; } const CustomCheckbox = (props: CustomCheckboxProps) => { const { children } = props; return ( <di ...

Spring Boot receiving null values from Angular form submission

I am currently working on a form in Angular that is used to submit information such as author, context, and recently added images. However, I have run into an issue where I am able to successfully retrieve the author and context, but not the images (it alw ...

RxJS: Transforming an Observable array prior to subscribing

I am retrieving data (students through getStudents()) from an API that returns an Observable. Within this result, I need to obtain data from two different tables and merge the information. Below are my simplified interfaces: export interface student Stude ...

Leveraging the left-hand side operator while invoking functions within Angular 2 templates

I've encountered a puzzling situation with the function in my component : public limit: number = 3 public logLimit(limit) { console.log(limit) } and in my template : <div (click)="logLimit(--limit)">Decrease and log limit</div> Stra ...

The error message "Module './style' and its type declarations cannot be located" is displayed by the TypeScript linter

Currently, I am in the process of developing a Gatsby project that utilizes css-modules and gatsby-config.js, specifically resolving a .scss extension within the project. The project is successfully building and functioning as intended. However, an issue ...

TypeScript modules located within the node_modules directory and then deployed within the wwwroot folder

Implementing this in an ASP.NET Core 2.x web application should have been straightforward considering it's a standard pattern. However, I seem to be doing something very wrong. Here is the folder structure that I am working with: projectRoot ├─â ...

The defaultValue of the Observable TextArea is blank space following the transmission of a sendMessage using SignalR in a Typescript

i am currently in the process of modifying a basic SignalR Chat feature. Here is the situation: when a user sends a message, the message gets sent successfully. However, the textarea from which it was sent remains filled with empty space (aside from the p ...

React with Typescript - Type discrepancies found in Third Party Library

Recently, I encountered a scenario where I had a third-party library exporting a React Component in a certain way: // Code from the third party library that I cannot alter export default class MyIcon extends React.Component { ... }; MyIcon.propTypes = { ...

Issue encountered in TypeScript: Property 'counter' is not found in the specified type '{}'.ts

Hey there, I'm currently facing an issue while trying to convert a working JavaScript example to TypeScript (tsx). The error message I keep encountering is: Property 'counter' does not exist on type '{}'.ts at several locations wh ...

Clicking on an element- how can I find the nearest element?

Encountering an issue with my next js app where I am attempting to assign a class to an element upon clicking a button. The problem arises when trying to access the next div using the following code snippet: console.log(e.target.closest('.request_quot ...

Roll out the new version of the npm package feature as a pre-release deployment

I am currently working on a React project that is packaged with tsbuild and then published to an npm package using Azure DevOps. Recently, I have observed an issue where when someone attempts to install the package by running yarn add packageName --latest ...

Click on an element in Angular to toggle it

A function in my codebase is responsible for toggling a specific section within a div element. Currently, there are a total of 3 sections available in the app. The functionality is implemented in the app.component.ts file: show = false; toggle() { ...