What is the best way to incorporate sturdy data types into the alternative function for this switch statement

const switchcase = (value, cases, defaultCase) => {
  const valueString = String(value);
  const result = Object.keys(cases).includes(valueString)
    ? cases[valueString]
    : defaultCase;
  return typeof result === 'function' ? result() : result;
};

I am looking for guidance on how to introduce type restrictions in the JavaScript function provided above without resorting to using any unless absolutely necessary. I understand that the value parameter may be of any type, but I'm seeking clarification regarding the types for cases, defaultCase, and the return value of the function.

Your insights would be greatly appreciated!

Answer №1

The function's return type is determined by what you want it to return.

One approach is to modify ExpectedReturnType to match your desired output, and ensure that your cases are of that type or functions with an arity of 0 that return the expected type.

interface ExpectedReturnType {}

// Each case can be a function that generates the return type
// or the type itself
type CaseType = ExpectedReturnType | (() => ExpectedReturnType);

const switchcase = (
  value: any,
  cases: { [key: string]: CaseType },
  defaultCase: CaseType
): ExpectedReturnType => {
  const valueString = String(value);
  const result = valueString in cases ? cases[valueString] : defaultCase;
  return typeof result === "function" ? result() : result;
};

You can also utilize generics:

function switchcase<T, U = T | (() => T)>(
  value: any,
  cases: { [key: string]: U },
  defaultCase: U
): T {
  const valueString = String(value);
  const result = valueString in cases ? cases[valueString] : defaultCase;
  return typeof result === "function" ? (result as Function)() : result;
}

// Implementation example:
const cases = { foo: "bar", whee: () => "yay" };
switchcase("foo", cases, "bar");

// Another example using specified type:
switchcase<string>("foo", cases, "bar");

Typescript should infer T from the parameters passed, but you can explicitly specify it as switchcase<SomeType>(...) if needed.

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

Exploring TypeScript interfaces with optional properties and returning types

As a newcomer to TypeScript, I am currently exploring the documentation and came across an example in the "Optional Properties" section that caught my attention: interface SquareConfig { color?: string; width?: number; } function createSquare(config: ...

Middleware transformation pipeline implemented using Typescript types

In my quest to create a function that empowers middlewares (specifically Express ones) to enhance the Request object by adding properties to it, I aim for subsequent middlewares in the chain to utilize these additions while preserving data types. An examp ...

Discovering Angular2 Heroes: Exploring the Purpose of the Colon in onSelect(hero: Hero)

Currently, I am working on the Angular2 tour of heroes project. You can check it out here. <li *ngFor="let hero of heroes" (click)="onSelect(hero)">{{hero.name}}</li> Within this project, I have a function that alerts the current hero's ...

Is TypeScript the new replacement for Angular?

After completing a comprehensive tutorial on Angular 1.x, I decided to explore Angular 2 on angular.io. However, upon browsing the site, I noticed references to Typescript, Javascript, and Dart. This left me wondering if my knowledge of Angular 1.x is now ...

Is it possible to retrieve a static resource within server-side code in NextJs?

Exploring the static render feature of NextJS to generate a static version of my website has led me to ensure that all necessary data is provided for the initial page render. I have stored several blog posts as .md files in /static and aim to access them ...

Derive the property type based on the type of another property in TypeScript

interface customFeatureType<Properties=any, State=any> { defaultState: State; properties: Properties; analyzeState: (properties: Properties, state: State) => any; } const customFeatureComponent: customFeatureType = { defaultState: { lastN ...

Can you showcase two distinct perspectives on a single page?

One of my components has nested ngFor directives looping through an array of users and their posts. I have a view link within this element, and when clicked, it should show detailed information about both the user and the post. However, the current setup i ...

Creating custom components in AngularJS 2 allows you to define methods unique to each component. Want to learn

I created my component (A) by combining multiple html elements, but I have two questions. How do I define methods (such as get, etc.) on my component? I have tried @Output, @ViewChild, etc. but they are not working. I am looking for an alternative way ...

Assign the onClick function to the decoration of a Vscode extension

When I click on a vscode decoration, I want to trigger a function. Here's the code I created for this: const decoration = { range, hoverMessage: `${command} ${input}`, command: { title: 'Run Function', command: ' ...

Dealing with TypeScript issues while implementing Multer in an Express application

import multer, { FileFilterCallback } from "multer"; import sharp from "sharp"; import { NextFunction, Request, Response } from "express"; const multerStorage = multer.memoryStorage(); const multerFilter = ( req: Request, ...

Creating a factory class in Typescript that incorporates advanced logic

I have come across an issue with my TypeScript class that inherits another one. I am trying to create a factory class that can generate objects of either type based on simple logic, but it seems to be malfunctioning. Here is the basic Customer class: cla ...

Upgrading Angular from version 8 to 9: Dealing with Compilation Errors in Ivy Templates

After successfully upgrading my Angular application from version 8 to version 9 following the Angular Update Guide, I encountered some issues in the ts files and managed to resolve them all. In version 8, I was using the View Engine instead of Ivy, which ...

React App Creation: Issue with ESLint configuration in TypeScript environment

I recently built a React app with the CRA (typescript template), but I noticed that TypeScript isn't adhering to the rules specified in the ESLint configuration. This is puzzling because I have consistently used this configuration in all my React proj ...

Display the default text using ngx-translate if a key is not found or while the translation file is loading

Currently in the process of setting up a brand new Angular 7 application. I am interested in establishing a default text for translation purposes. Specifically, when utilizing the translation {{ 'wait' | translate }}, I would like to ensure that ...

Encountering Issues with NextJS Dynamic SSR: Mobile Devices stuck on loading screen

Issue: The dynamic import feature of Next JS is encountering loading issues specifically on mobile browsers such as Google Chrome and Safari on IOS. Strangely, the functionality works smoothly on desktop browsers like Google Chrome and Mozilla. The projec ...

The attribute 'pixiOverlay' is not found in the property

Working on my Angular 8 project, I needed to display several markers on a map, so I chose to utilize Leaflet. Since there were potentially thousands of markers involved, I opted for Leaflet.PixiOverlay to ensure smooth performance. After installing and imp ...

What is the reason the 'Add' type does not meet the 'number' constraint?

I experimented with type gymnastics using Typescript, focusing on implementing mathematical operations with numeric literals. First, I created the BuildArray type: type BuildArray< Length extends number, Ele = unknown, Arr extends unknown ...

establishing the default value as p-multiselect

Here is the code snippet I am currently working on: export class LkBoardStatus { id : number = 0; descr : string = ''; } In the component.ts file, I have defined the following: //... lkBoardStatusList: LkBoardStatus[] = []; selectedStat ...

Integrating d3.js into an Angular 2 project

Trying to incorporate the d3.js library into a MEAN application using angular2. Here are the steps I've taken: npm install d3 tsd install d3 In mypage.ts file (where I intend to show the d3.js graph) // <reference path="../../../typings/d3/d3.d ...

Allow Visual Studio Code to create a constructor for Typescript class

When developing Angular 2 apps in Typescript using Visual Studio Code, one common task is writing constructors with their parameter list. Is there a way to save time and effort on this? It would be really helpful if the IDE could automatically generate th ...