Can one deduce the generic type from within a string template literal?

I have a piece of code that achieves my desired outcome, but I want to avoid explicitly specifying the generic it requires.

type EventGroup = {
  actions: "run" | "save"
  other: "bla"
}

export type EventType<T extends keyof EventGroup> = `${T}/${EventGroup[T]}`

const t: EventType<"actions"> = "actions/run"

I am hoping that Typescript can automatically infer the following:

`actions/run` -> valid
`actions/save` -> valid
`actions/bla` -> NOT valid
`other/bla` -> valid

The code currently accomplishes this, but I would like to eliminate the need for an explicit generic.

Answer №1

To achieve this, you can utilize a mapped type to combine the values:

export type EventType = {
    [K in keyof EventGroup]: `${K}/${EventGroup[K]}`
}[keyof EventGroup];

Here is a test of the type's validity:

const t1: EventType = "actions/run";  // valid
const t2: EventType = "actions/save"; // valid
const t3: EventType = "actions/bla";  // NOT valid
const t4: EventType = "other/bla";    // valid

Interactive example

This process involves two components, starting with the mapped type:

type EventType = {
    [K in keyof EventGroup]: `${K}/${EventGroup[K]}`
}

which results in:

type EventType = {
    actions: "actions/run" | "actions/save";
    other: "other/bla";
}

Lastly, we use [keyof EventGroup] to extract only the values from actions and other as a union.

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 functionality of the MVC jQuery grid is currently malfunctioning

Recently, I attempted to integrate a jQuery grid plugin from gijgo.com into my MVC application. Following the instructions provided on c-sharpcorner and/or codeproject meticulously, however, upon running the application, I encountered a troubling JavaScrip ...

What is the reason file inputs do not trigger 'input' events, while 'change' events do fire?

Trying out a basic input: <input type="file"/> Noticing that the input event doesn't trigger when a new file is selected: $('input').on('input', function(event){ console.log('input value changed', event.targe ...

Why am I unable to utilize res of type NextResponse in my API endpoint?

I currently have a dynamic API route file specifically designed for handling POST requests. Below is the code snippet of this file: import { NextRequest, NextResponse } from "next/server"; import dbConnect from "@/lib/dbConnect"; import ...

Using Javascript to swap out elements sharing the same classname with distinct contents

Just a quick question: Can you replace the values of elements with the SAME class with different values? For example, let's say I have this array returned by an AJAX response: [ "$63.00 / Night", "$68.00 / Night", "$58.00 / Night", "$50.00 / ...

outputting javascript within php

I'm struggling to extract the data returned by AJAX after a successful call. Instead of just getting the words printed by my JavaScript code, I end up with the entire script that is echoed in the PHP file. What I really need are only the words outputt ...

What is the best approach for defining variables in typescript?

Let's talk about creating a variable for a car: export class ICar { wheels: number; color: string; type: string; } So, which way is better to create the variable? Option one: const car = { wheels: 4, color: 'red', type: &apos ...

Guide on sending a PUT request using express.js

Currently delving into node.js and have a query regarding PUT requests I'm able to create an object and see it in the URL. However, I'm unsure of how to write a request to edit it - such as changing the price of a vehicle. Any guidance on writin ...

What is the most effective way to accurately identify the mobile platform of a user using JavaScript?

I need to determine whether a user has accessed the application through a browser on Android or iOS. The company would like to display slightly different content depending on the platform. While I am aware that navigator.platform can be used for this pur ...

Tips for maintaining accessibility to data while concealing input information

Is it possible to access data submitted in a form even if the inputs were hidden by setting their display to none? If not, what approach should be taken to ensure that data can still be sent via form and accessed when the inputs are hidden? ...

Encountering a 404 error for .ts files: The mystery of the missing

Whenever I try to access a page on my live environment, an error appears: GET http://example.com/Scripts/main.ts 404 (Not Found) error: (SystemJS) XHR error (404 Not Found) loading http://example.com/Scripts/main.ts This issue does not occur in my ...

Creating a custom route in Node.js using Express for posting content and adding it to a specific user's page

I am currently working on a node.js express project where I am developing a health app for a trainer to manage his clients. The main functionality of the app includes allowing the trainer to access individual client profiles and view their exercise list by ...

What is the best way to extract a value from an input within a filter?

I am currently utilizing ngx-easy-table in my application. I am trying to retrieve the input filter value on keyup event, but I have not been able to find any helpful information in the documentation. Does anyone have any insights or suggestions on how to ...

The issue persists with the ajax.reload() function in DataTables

It's been driving me crazy that my datatables table won't refresh, despite using ajax.reload. I've spent weeks on this code but still can't get it to work. DataTablesDraw = (selector, order, pages, file, sort, column, template, data_se ...

Node.js is a versatile platform that allows users to efficiently download zip files into a folder and extract its contents. Discovering the optimal time to commence unzipping the file can be

Looking to create two distinct components - first, a downloader that can take either a file path or a FILE DESCRIPTOR and a URL, then proceed to download the file from that URL into the specified path. To view the code I've developed for the downloade ...

Using JavaScript to post data to a PHP script, then triggering the execution of another

My website has two distinct pages with different purposes. On one page, there is a button that, when clicked, sends data to finalizecontract.php. The other page, contract.php, creates a TCPDF form populated with the database information and saves the resu ...

Ajax is working effectively as the first post is successful and the second post is able to retrieve data

UPDATE: I resolved the issue by relocating my form submitter script from the Header to the bottom of the jamesmsg.php page (the included one). By doing this, the functions are always re-loaded and attached to the "new" form each time the div is refreshed. ...

How do I connect with the global error handling in Vue?

Within my Vue2 application, I am seeking a method to capture global Vue errors and transmit them to a logging or monitoring service such as Sentry. After attempting to overwrite the global error handler of Vue, I noticed that console logs were no longer a ...

Altering the JavaScript variable by selecting an option from a dropdown list

After downloading a choropleth map from leafletjs.com, I encountered an issue with multiple JS files labeled by year (e.g. us-states2012.js, us-states2013.js). The challenge now is to implement a drop down menu in such a way that selecting a specific year ...

Tips for creating a unique identifier for each component when initializing the useState() function

I need assistance with creating 30 empty Taskcard components in the state. The issue is that each Taskcard is assigned the same id. How can I resolve this problem? import React from 'react' import { useEffect, useState } from 'react' ...

Retrieve the parent jQuery object of the element that was clicked using jQuery

Within my HTML code, I have numerous instances of elements similar to the following: <div class="class"> <div class="disconnect_btn">Click here</div> <input type="hidden" name="ID" value="12"/> </div> I've set up a ...