Using parametric types as type arguments for other types in TypeScript or Flow programming languages

Consider the various types showcased for demonstration:

type TranslateToEnglish<A extends string> = 
  A extends "1" ? "one" :
  A extends "2" ? "two" :
  A extends "3" ? "three" :
  "etc";

type ConvertNumberToString<A extends string> =
  A extends `${infer C}${infer Tail}` ? 
    `${TranslateToEnglish<C>}-${ConvertNumberToString<Tail>}` : "";

For instance, using

ConvertNumberToString<"12">
will yield "one-two-".

Now, the goal is to increase its flexibility and allow a "translator" like TranslateToEnglish to be passed as an argument:

type ConvertWithTranslator<A extends string, Translator> =
  A extends `${infer C}${infer Tail}` ? 
    `${Translator<C>}-${ConvertNumberToString<Tail>}` : "";

This approach fails with the error:

Type 'Translator' is not generic. ts(2315)

Attempting to revise it as below results in another error:

type ConvertWithTypeParam<A extends string, Translator<_>> = 

The error message shows: ',' expected. ts(1005) at the <_>.

Q: Is there a method to pass a parametric (generic) type as an argument to another type within TypeScript, Flow, or other JavaScript superset? Similar to higher-order functions but for types.

Answer №1

My recommendation involves implementing a solution that removes the need to directly pass the generic type as a type parameter. Instead of doing that, you can create a record of translators and then simply pass the name of a specific translator to access the type:

Check out the Playground for this example

type ToEnglish<A extends string> = 
  A extends "1" ? "one" :
  A extends "2" ? "two" :
  A extends "3" ? "three" :
  "etc";

type ToSpanish<A extends string> = 
  A extends "1" ? "uno" :
  A extends "2" ? "dos" :
  A extends "3" ? "tres" :
  "etc";


type TranslatorMap<A extends string> = {
    English: ToEnglish<A>;
    Spanish: ToSpanish<A>;
}

type ConvertGeneric<A extends string, Translator extends keyof TranslatorMap<A>> =
  A extends `${infer C}${infer Tail}` ? 
    `${TranslatorMap<C>[Translator]}-${ConvertGeneric<Tail, Translator>}` : "";

type EnglishTest = ConvertGeneric<"12", "English">
type SpanishTest = ConvertGeneric<"12", "Spanish">


Answer №2

This code snippet demonstrates how to use flowjs with a type constructor in JavaScript:

// @flow

type TypeConstructor = <V>() => {updated:V};

type Obj = {
  a: number,
  b: string
}

type Result = $ObjMap<Obj, TypeConstructor>

const ok:Result = {
  a: {updated:42},
  b: {updated:42}
}; // this is valid

const error:Result = {
  a: 42,
  b: 42
}; // this will throw an error

The TypeConstructor acts like a callback function, converting one type to another. Each key/value pair in the obj object is passed through the TypeConstructor. This functionality is not achievable in TypeScript due to its requirement for explicit generics.

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 potential arrays within a JSON file using TypeScript

Seeking guidance on a unique approach to handling array looping in TypeScript. Rather than the usual methods, my query pertains to a specific scenario which I will elaborate on. The structure of my JSON data is as follows: { "forename": "Maria", ...

Is there a way to adjust the starting and ending points of a bezier curve in D3 by utilizing the link generator?

I'm currently working on developing a horizontal hierarchical tree Power BI custom visual using TypeScript and D3. I am utilizing d3's treeLayout for this purpose, and my task is to create a link generator that can plot bezier, step, and diagonal ...

Having trouble getting useFieldArray to work with Material UI Select component

I am currently working on implementing a dynamic Select field using Material UI and react-hook-form. While the useFieldArray works perfectly with TextField, I am facing issues when trying to use it with Select. What is not functioning properly: The defau ...

Combining 2 lists in Angular Firebase: A Simple Guide

I have been searching for a solution for the past 2 hours, but unfortunately haven't found one yet. Although I have experience working with both SQL and NoSQL databases, this particular issue is new to me. My problem is quite straightforward: I have t ...

Demonstrate JSON data using ngFor loop in Angular

Need some assistance here. Trying to display data from a .json file using a ngFor loop. However, I keep running into the following error in my code: Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgF ...

Absent 'dist' folder in Aurelia VS2015 TypeScript project structure

After downloading the Aurelia VS2015 skeleton for typescript, I encountered an issue trying to run the Aurelia Navigation app in IIS Express. One modification that was made to the skeleton was adding "webroot": "wwwroot" to the top level of project.json. ...

What is the process for displaying the attributes of a custom object in Typescript?

I need help returning an array of prop: value pairs for a custom object using the myObject[stringProp] syntax. However, I keep encountering this error message: TS7053: Element implicitly has an 'any' type because expression of type 'str ...

Clicking on the React Bootstrap Checkbox within the Nav component does not trigger a rerender of the NavItem component

Encountering an unusual issue while using a Nav and NavItem with a Checkbox from React Bootstrap. What I've noticed is that when clicking directly on the checkbox instead of the NavItem button, the checkbox does not re-render correctly even though my ...

Creating a bespoke numeric input component using React Native

As I work on developing a numericInput component, my goal is to streamline the code by eliminating RNTextInput. The part that confuses me is how it utilizes React.forwardRef<RNTextInput, Props>((props, ref) => { const { onChangeText, ...rest } ...

Tips for updating parameters that are defined in a controller within a promise

Currently, I am developing a single page application using Angular and TypeScript. I am facing an issue with updating the parameter value (_isShowFirst) of the controller inside a promise function. It seems like nothing is recognized within the promise blo ...

Retrieving the data from a Material UI Slider control

I'm encountering an issue with retrieving the value property I assigned to a component. event.target.value is returning undefined. How can I successfully access the value of the component? My goal is for handlePlayersChange() to be able to handle dyn ...

Angular 2 select does not recognize the selected option

In my Angular 2 code, I am using ngFor to populate a dropdown with options. I want a specific option at a certain index to be selected by default. Currently, I tried using [attr.selected]="i == 0" but it ends up selecting the last option instead of the fi ...

Inquiry regarding modules in Javascript/Typescript: export/import and declarations of functions/objects

I'm fresh to the realm of TypeScript and modules. I have here a file/module that has got me puzzled, and I could really use some guidance on deciphering it: export default function MyAdapter (client: Pool): AdapterType { return { async foo ( ...

Retrieve a particular element from an array within a JSON object using Ionic

I am currently facing a challenge in extracting a specific array element from a JSON response that I have retrieved. While I can successfully fetch the entire feed, I am struggling to narrow it down to just one particular element. Here is what my service ...

The use of Next.js v12 middleware is incompatible with both node-fetch and axios

I am facing an issue while developing a middleware that fetches user data from an external endpoint using Axios. Surprisingly, Axios is not functioning properly within the middleware. Below is the error message I encountered when using node-fetch: Module b ...

After pressing the login button, my intention is to transition to a different page

I am relatively new to web development and working with angular. I have a login component that, upon hitting the LOGIN button, should redirect to another component on a different page. However, currently, when I click the button, it loads the data of the o ...

Creating a shared singleton instance in Typescript that can be accessed by multiple modules

Within my typescript application, there is a Database class set up as a singleton to ensure only one instance exists: export default class Database { private static instance: Database; //Actual class logic removed public static getInstance() ...

Generate an array of objects by combining three separate arrays of objects

There are 3 private methods in my Angular component that return arrays of objects. I want to combine these arrays into one array containing all the objects, as they all have the same class. Here is the object structure: export class TimelineItemDto { ...

Ways to retrieve a Class Level Variable within the onCellValueChanged function in agGrid

Exploring Angular with Typescript for the first time. I'm trying to access Class Level Variables within the onCellValueChanged event of agGrid, but encountering the following error: Cannot read property 'updateDict' of undefined Here&apo ...

Integrating Vimeo videos into Angular applications

I am attempting to stream videos using URLs in my Angular application. Every time I try, I encounter the following error: Access to XMLHttpRequest at 'https://player.vimeo.com/video/548582212?badge=0&amp;autopause=0&amp;player_id=0&amp;ap ...