What are some typical ways Generics are used in Typescript?

Trying to comprehend the practical application of Typescript generics in real-life scenarios, beyond just niche cases, is a common challenge. While it's understood that generics provide an additional layer of abstraction to enable reuse of functions/classes/interfaces in various contexts, some might argue that unions and intersection types could serve a similar purpose with a certain level of generality.

However, consider the following example:

interface Identities<V, W> {
   id1: V,
   id2: W
}

function identities<T, U> (arg1: T, arg2: U): Identities<T, U> {   
 let identities: Identities<T, U> = {
    id1: arg1,
    id2: arg2
  };
  return identities;
}

This ensures strict type matching for the return value based on the argument types provided.

Imagine a scenario where you need your function/class to accommodate diverse arguments, as long as they adhere to specific constraints:

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);  // By checking for the .length property, we eliminate potential errors
    return arg;
}

This illustrates how such constructs can be beneficial in particular contexts.

Answer №1

Within the realm of computer science, Generics are referred to as Parametric Polymorphism, showcasing their practical utility quite effectively (assuming one comprehends the concept).

But what exactly does this term signify?

To start with, let's examine the general meaning of "parametric." Essentially, it denotes the presence of parameters. It's universally acknowledged that parameters play a vital role. A function restricted to adding just 3 and 5 might be mundane. Conversely, a function capable of adding any pair of numbers while being parameterized based on those numbers is undeniably more versatile!

A type constructor (the computer science terminology for a generic type) generates a type from another type. The apt nomenclature 'type constructor' draws parallels to certain branches of mathematics where functions are deemed as 'constructors' or 'value constructors' since they produce new output values leveraging input values. Similarly, a type constructor operates at the type level; not at the value level.

Consider the Promise type constructor—requiring a single argument like

number</code—to craft a <em>new type</em> denoted as "NumberPromise."</p>

<p>The rationale behind leveraging type constructors with parameters on the type level aligns with the logic favoring functions with parameters on the value level: facilitating the creation of novel entities from pre-existing ones.</p>

<p>Why is <em>parametric polymorphism</em>, more precisely where the type parameter remains entirely unspecified, considered beneficial? </p>

<p>Recall the broader notion of <em>polymorphism</em>: enabling code to execute operations across diverse types.</p>

<p>The prevalent form of polymorphism—<em>ad-hoc polymorphism</em—entails the code carrying out <em>dissimilar operations for each type</em> necessitating distinct, specific implementations tailored to every type under consideration. Object-oriented virtual method dispatch stands as an illustrative instance of ad-hoc polymorphism wherein each class contains its own distinctive method implementation.</p>

<p>(In practice, object-oriented programming typically amalgamates <em>subtype polymorphism</em> with ad-hoc polymorphism, supporting <em>differential code-reuse</em> where subtype implementations selectively alter inherited supertype behaviors via inheritance or prototype delegation.)</p>

<p>In contrast, parametric polymorphism harbors solely a <em>single operation</em> functional across <em>every conceivable type</em>. An elementary example involves a function computing the length of a singly-linked list, indifferent towards the element types; hence, being <em>parametric</em> regarding the element type, exemplified through:</p>

<pre class="lang-js"><code>function length<T>(list: List<T>) {
  return list.rest === undefined ? 0 : 1 + length(list.rest);
}

This function abstains from engaging with the list elements directly, thereby offering generic functionality unrestricted by the element type.

Another case in point pertains to the identity function:

function id<T>(it: T) {
  return it;
}

All these functions epitomize fully parametric behavior operating on any provided type argument devoid of concerns about the actual type per se.

Nevertheless, instances do exist where functions must possess some comprehension concerning the involved types. For example, a sort operation mandate knowledge pertaining to sortable elements by establishing certain "bounds" around the type parameters, embodying bounded polymorphism:

interface Comparable<T> {
  const enum Comparing {
    LessThan = -1,
    Equal,
    GreaterThan
  }

  compareTo(other: T): Comparing
}

function sort<T extends Comparable<T>>(list: List<T>) {
  // sorting algorithm implementation
}

Addressing your query about modeling utilizing union and intersection types, a fundamental differentiating factor lies in how parametric polymorphism treats the type as an argument stipulated by the user. Attempting to model a generic collection class through a union of all probable element types would entail cataloging every imaginable type ever conceived in advance—a clearly impractical endeavor. Anticipating every type feasible to populate a list, map, or array in meticulous detail proves infeasible.

Alternatively, contemplate function types: imposing a stringent requirement for functions to solely interact with a predefined exhaustive union of types expressly outlined by TypeScript developers appears overly restrictive, doesn't it?

An insightful post on Software Engineering delves into analogous facets albeit from a divergent perspective. While the discussion centers on C#, which exhibits greater rigidity relative to TypeScript due to lacking support for union or intersection types, you're bound to unearth pertinent insights:

  • Generics vs common interface: Delving into the versatility of generics beyond collections and querying why restricting collections to a singular generalized type isn't preferable.

Answer №2

When making API calls, Generics offer a neat way to store extra data:

Consider an API response:

value: {} // this is generic
messages: [] // additional logging/errors/warnings
// other properties that apply for all objects

In Typescript:

export interface GenericResponse<T> {
  value: T;
  messages: ApiMessageItem[];
 // additional properties
}

The 'T' in this case represents any object retrieved from the API.

While using Unions is an option, utilizing generics seems more organized, especially when dealing with multiple API objects.

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

Challenges encountered when using random values in Tailwind CSS with React

Having trouble creating a react component that changes the width based on a parameter. I can't figure out why it's not working. function Bar() { const p =80 const style = `bg-slate-500 h-8 w-[${p.toFixed(1)}%]` console.log(styl ...

What is the process for sending a GET request to fetch the most recent document from an index in the Elasticsearch cluster?

I've been working on a node.js application to fetch the most up-to-date index value from an elastic cluster. The data is streamed from my logstash server into elasticsearch every second, resulting in the index being updated with a new document added e ...

Request was unsuccessful due to error code 400, which indicated a problem with the given MP4 file in the

I've been working on streaming an mp4 file from my computer. I can successfully upload and delete files, but when I click the link after uploading, all I see is {}. Additionally, I'm getting the following errors: GET http://localhost:8000/read/c9 ...

Tips for integrating AudioControl with Phonegap

I couldn't find a suitable plugin, so I decided to create my own. My goal is to activate silent mode using a JavaScript command, however, I am encountering an error with the undefined method getSystemService. It seems like there may be a problem with ...

Challenges faced when attempting to launch a React-powered application on Railway platform

When I transferred my fullstack app (React + Express) from Heroku, I encountered an issue. React apps need to be built to run and require necessary dependencies installed, but typically only raw source code is stored on Git. A typical structure for fullst ...

How can I pre-fill an AutoModelSelect2Field with static information in Django using the django-select2 library?

I am currently using a field similar to the one below: class ContactSelect(AutoModelSelect2Field): queryset = Contact.objects.all() search_fields = ['name__contains'] to_field = 'name' widget = AutoHeavySelect2Widget W ...

How can I open a modal dialogue using ClientClick in an ASP.Net application?

It seems like a common issue with ASP.Net web applications where opening a dialog box before executing onClick events can be problematic. OnClientClick and OnClick events are both attached to the same ASP button, causing issues in the execution sequence. ...

Issues with the startCellEditMode function in React MUI are preventing successful activation

Working with a Datagrid in Material-UI, I have implemented edit buttons for each row within the actions of a column definition. Looking at the documentation, I found the startCellEditMode function in MUI which can be used like this: const handleEditClick ...

Using browserify with html2canvas is causing compatibility issues

When I initially tested html2canvas as a standalone script, it worked perfectly. However, when attempting to use the npm package version, it is proving to be quite uncooperative. Essentially, it does not execute any actions or trigger the then function. T ...

CDK Continuous Integration/Continuous Deployment pipeline encountering difficulties locating references within stack for deployment

My goal is to set up a cdk cicd pipeline for an app that already has a cdk stack and deploys successfully manually with cdk deploy. I want the cdk pipeline to automatically deploy the stack whenever changes are pushed to the main branch so that it's n ...

Managing optgroup in select dropdown using Angular 4

Is there a way to retrieve the optgroup label value within an onchange function on a select box in Angular 4? In my form, I have a select box with multiple dates as option groups and time slots in 24-hour format for booking (e.g. 1000 for 10AM, 1200 for 1 ...

A guide to creating a TypeScript redux middleware class

As specified in the typescript definition for Redux, these interfaces must be implemented to create middleware: /* middleware */ export interface MiddlewareAPI<D extends Dispatch = Dispatch, S = any> { dispatch: D getState(): S } /** * A midd ...

Generating, establishing aesthetics for a specific span

My goal is to automatically detect addresses within a page and apply the class "address" where they are found. var addressPatternApplier = function(element, pattern, style) { var innerText = element.innerText; var matches = innerText.match(pattern); ...

initialize state using shorthand property in class components

I came across some code recently that caught my eye. It appears to be neat and organized, but there are a few things that seem out of the ordinary to me. Why is state = {} declared without a constructor? Additionally, why is load declared without using th ...

Troubleshooting: Unable to switch i18n language in TS/ReactJS

Recently, I integrated TypeScript into my project and encountered an issue with my i18n system. Previously, everything was working smoothly with the language toggle using "i18n.changeLanguage([language])". However, since transitioning to TypeScript, the to ...

Getting a ThreeJS element, specifically a mesh, by its ID

I am working with a Mesh object in Three.JS. Is there a way to retrieve the Mesh object by its id and adjust its position, similar to using $(#"sample") in jQuery? Alternatively, do you have any suggestions for changing the position of objects in the ...

Save this text in HTML format to the clipboard without including any styling

When using this code to copy a htmlLink to the clipboard: htmlLink = "<a href='#'>link</a>"; var copyDiv = document.createElement('div'); copyDiv.contentEditable = true; document.body.appendChild(copyDiv); ...

Retrieving information from a JSON document in IONIC with the help of AngularJS

Issue After using the ionic tabs template to create my first project with the ionic framework, I noticed that the data for friends and friend details is being pulled from an array list in the services.js file. However, I would like to instead fetch this d ...

Is it possible to run a Vue file autonomously, similar to an HTML file

When it comes to running html, we can rely on mainstream browsers such as Chrome. But is there a similar tool for vue files, like the browsers designed for html? ...

Frontend not displaying errors despite using express-validator

Currently experimenting with nodejs, I have passportjs configured and trying to implement validation for the register form. Here is my current setup, route // Register :post router.post('/dashboard/register', body('firstname').notEmpt ...