Creating a refined parameter type in Typescript using a discriminator

Looking to work with a legacy API that has the following structure (playground link)...

type Command1 = {
    cmd: "my first command",
    arg1: string,
    arg2: boolean
}

type Command2 = {
    cmd: "my second command",
    foo: string,
    bar: number
}

type Command = Command1 | Command2

function execute(cmd: Command["cmd"], args:any /* would like to strongly type this */) {
    console.log(args)
}

execute("my first command", {/* oops missing props */})

Seeking a method to ensure type checking for the args parameter of the execute function without altering the function's parameter list. Any suggestions?

Appreciate any insights. Thank you.

Answer №1

Make sure to utilize the Extract<Type, Union> method by visiting this interactive playground:

function run<Task extends Job["task"]>(
  task: Task, 
  parameters: Omit<Extract<Job, { task: Task }>, "task">
) {
    console.log(task, parameters)
}

// run<"task A">(task: "task A",   parameters: Omit<Job1, "task">): void
run("task A", { param1: "value1", param2: true })

// run<"task B">(task: "task B", parameters: Omit<Job2, "task">): void
run("task B", { foo: "bar", baz: 123 })

Answer №2

Have you considered utilizing an intersection type with generics in this scenario? Assuming the remaining code aligns with your provided example:

function execute<T extends Command["cmd"]>(cmd: T, args: Command & { cmd: T }) {
    console.log(cmd, args)
}

It seems like a practical approach to effectively combine the discriminator and the appropriate type of Command.

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

What is the best way to extract the ID from an event in TypeScript?

HTML Code: <ion-checkbox color="dark" checked="false" id="1on" (ionChange)="onTap($event)" ></ion-checkbox> TypeScript Code: onTap(e) { console.log(e); console.log(e.checked); } I am trying to retrieve the id of the checkbox. H ...

The method getManyAndCount() in TypeORM does not include related data in its return result

I'm completely new to TypeORM and NestJs. Currently, I am working on a project where I have an entity called VehicleModel which has a ManyToOne relationship with VehicleBrand. However, when I execute getManyAndCount() on my query, I am puzzled as to ...

React: The useContext hook does not accurately reflect the current state

I'm currently facing a dilemma as I attempt to unify data in my app. Whenever I click the button, the isDisplay value is supposed to be set to true; even though the state changes in my context file, it does not reflect in the app. Thank you for your ...

Angular: "btn" class vanishes when the button is toggled

I am facing an issue with the button's class change functionality. I am using the [ngClass] directive to switch between Bootstrap classes for the button style. However, when I click the button, the "btn" class seems to disappear from the code. Instead ...

Sending the chosen dropdown ID to a different component

In my application, there is a component named list where I am showcasing all the names of my customers in a dropdown, as illustrated below: https://i.sstatic.net/KEmAG.png When a particular item (i.e., customer) is selected from the dropdown, I would lik ...

Struggling with the incorporation of Typescript Augmentation into my customized MUI theme

I'm struggling with my custom theme that has additional key/values causing TS errors when I try to use the design tokens in my app. I know I need to use module augmentation to resolve this issue, but I'm confused about where to implement it and h ...

Failure in SystemJS during ahead-of-time compilation due to missing NgZone provider

Previously, I have successfully used Angular's ahead-of-time compilation. However, after adding routing and lazy loading to my app, I am facing difficulties in making it work again. Upon updating my code to the latest 2.0 release, it functions well w ...

How to retrieve an array stored within a JSON object

I am trying to access a specific array within an object from a JSON file. Here is the snippet of the data I'm dealing with: best-sellers": [ { "title": "Chuteira Nike HyperVenomX Proximo II Society", "price": 499.90, "installmen ...

Typescript-optimized Npm library utilizing the module-alias feature

As I work on creating an npm library with Typescript, I have made use of the paths setting in tsconfig.json and the module-alias tool to streamline my imports, allowing me to use syntax like import * from '@/utils'. However, I have encountered an ...

Error with scoped slot typing in Vue3 using Vite and Typescript

I am currently working on a project using Vue3, Vite, and TypeScript as the devstack. I encountered an error related to v-slot that reads: Element implicitly has an 'any' type because expression of type '"default"' can't ...

Module '. ' or its corresponding type declarations cannot be located

While working on my project with TypeScript and using Cheerio, I encountered an issue when trying to compile it with TSC. The compiler threw the following exception: error TS2307: Cannot find module '.' or its corresponding type declarations. 2 ...

Can the ngx-chips library be used to alter the language of chips?

Currently, I am working with the ngx-chips library and encountering a particular issue. Here is an image representation of the problem: https://i.sstatic.net/GL3Fd.png The challenge I am facing involves updating the language of the chips based on the sele ...

There are a pair of Ionic2 menus; one is currently visible while the other remains hidden

I am having an issue with my Ionic2 app where I have two pages, each with similar menus named XXX.html. One page displays its menu correctly, but the other does not show its menu at all. Is there a limitation in Ionic2 that prevents having two menus on the ...

Set the initial index position to 0 for the property type

Looking to define a type for the following scenario: categories.categories[0].category.map((c: CategoryObject) => ({ category: c.name[0]._text[0], Can we specify index 0 in the type declaration? For example: type CategoryObject = { name[0]: { _te ...

Gaining entry to specialized assistance through an occasion

Having trouble accessing a custom service from a custom event. Every time the event is fired, the service reference turns out to be null. @Component({ selector: "my-component", template: mySource, legacy: { transclude: true } }) export class myComponent { ...

Ensure that TypeScript compiled files are set to read-only mode

There is a suggestion on GitHub to implement a feature in tsc that would mark compiled files as readonly. However, it has been deemed not feasible and will not be pursued. As someone who tends to accidentally modify compiled files instead of the source fil ...

how to verify if a variable exists in TypeScript

Is there a recommended method for verifying if a variable has a value in TypeScript 4.2? My variable may contain a boolean value. I'm thinking that using if(v){} won't suffice as the condition could be disregarded if it's set to false. ...

Exploring the capabilities of renderOption within Material-UI's AutoComplete functionality

Hey there, I've been pondering a question lately and could really use some help. I've been trying to set up my autocomplete feature to display a label in the options while having a different value. After doing some research, I learned about usin ...

Troubleshooting: Resolving the Error "Cannot find Property htmlFor on Custom React Component"

I am currently working with a custom component that looks like this: import React from "react"; import classnames from 'classnames'; import { ButtonVariantColor } from '../types/button'; export type IconButtonProps = { e ...

The function 'ShouldWorkController' was expected but is not defined, receiving undefined instead

Whenever I attempt to connect a controller to a template using the angular-ui-router $stateProvider, I encounter this error message: 'ShouldWorkController' is not a function. Got undefined. Surprisingly, when I define the controller within the ...