Practical application of generics in TypeScript

I'm struggling to understand the practical use of generics in typescript.

interface ICustomer
{
  name: string;
  age: number;
}


function CalculateAverageAge<c extends ICustomer>(customer1: c, customer2: c): number
{
  return (customer1.age + customer2.age)/2;
}


resultingNumber = CalculateAverageAge({name: "Peter", age: 62},
                                   {name: "Jason", age: 33});

In the given example, we pass interface 'c' to the function CalculateAverageAge.

However, without using 'extends ICustomer', we cannot access 'age' and 'name' inside that class.

So what is the purpose of passing 'template(c)' in the function? We could just write the code in the following format:

function CalculateAverageAge(customer1: ICustomer, customer2: ICustomer): number
{
  return (customer1.age + customer2.age)/2;
}

Can you provide a real-world example where generics are truly beneficial?

Let me explain a scenario where I find using generics necessary.

interface t1{
a:String
b:number

}
interface t2 {
a:String
b:number
c:number
}
interface t3 {
a:String
b:number
d:number
}

class base<T extends t1> {
    constructor( input : T, type:string ){

        //some common code for both derived1 and derived2
        if(type==="derived1"){
        console.log(input.c);// will throw error because t1 doesn't contain c
        } else if ( type==="derived2"){
            console.log(input.d);// will throw error because t1 doesn't contain d
        }
    }
}

class derived1 extends<t2>{
constructor(){
var temp = {a:"11",b:2,c:3}
super(temp,"derived1");
}
class derived2 extends<t3>{
constructor(){
var temp = {a:"11",b:2,d:3}
super(temp,"derived2");
}
}

Is it possible to achieve this with generic?

If not, what would be the most efficient way to implement it while avoiding redundant code?

Answer №1

As illustrated in your scenario, the interface proves to be sufficient.

Generics become valuable when aiming for a more versatile solution; at times, the requirement is so broad that an interface may not even be necessary. The instance you mentioned is not solely generic but also establishes constraints on the form of the generic through an interface.

Another use case for generics could involve creating a collection capable of accommodating various types of elements. For example, the array type in TypeScript exemplifies this concept -

var a = new Array<number>()
.

Consider wanting to build a function that compares two items, much like the following:

interface IValue { value: number; }

function max(a: IValue, b: IValue): IValue {
    return a.value > b.value ? a : b;
}

The issue here lies in the fact that the max function yields its result as an IValue, which may not always be desirable. What you may truly need is something along these lines:

interface IValue { value: number; }

function max<T extends IValue>(a: T, b: T): T {
    return a.value > b.value ? a : b;
}

In this revised version, the return type of max corresponds to whatever the generic type T represents, thereby presenting a more advantageous approach.

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

Using Typescript to overload functions with varying first parameters

I am facing a scenario where I have a parent class that requires a method implementation with either one or two parameters depending on the child class. class MyClass { update(obj: HashMap); update(id: ID, obj: HashMap); update(objOrId: HashM ...

What is the best method to extract the values of objects in an array that share

var data= [{tharea: "Rare Disease", value: 3405220}, {tharea: "Rare Disease", value: 1108620}, {tharea: "Rare Disease", value: 9964980}, {tharea: "Rare Disease", value: 3881360}, ...

Angular 2 ngFor generates a collection of rows and columns forming a single large column

It seems that ngfor is generating divs one by one, resulting in a poor design where they are stacked on top of each other. I would like to achieve a layout like this: [1] [2] [3] [4] [5] [6] However, the current outcome looks like this: [ 1 ] [ 2 ] [ 3 ...

Apollo GraphQL has initiated the detection of a new subscription

My approach involves utilizing graphql-ws for subscribing to GraphQL events. I rely on the Observable interface to listen to these events. Although I can use the error callback to identify when a subscription fails to start, it is challenging to determine ...

Is it recommended to employ cluster connection within my Redis client when utilizing Azure Redis Cluster?

It seems that the Azure documentation on clustering can be a bit confusing. According to the docs: Will my client application need any modifications to support clustering? Once clustering is activated, only database 0 will be accessible. If your client ...

Understanding the Relationship Between Interfaces and Classes in Typescript

I’ve come across an interesting issue while working on a TypeScript project (version 2.9.2) involving unexpected polymorphic behavior. In languages like Java and C#, both classes and interfaces contribute to defining polymorphic behaviors. For example, i ...

Optimizing your data layer in Angular2: A Guide to Best Practices

As a newcomer to Angular2, I am diving into hands-on learning. My current project involves building multiple views with parent components, child components, and database services. After successfully creating one view, I am now gearing up to implement other ...

Set a field to mandatory or optional depending on a condition in serenity-platform

Currently, I am tackling a project on the serenity platform. Does anyone have suggestions on how to dynamically change the field's required status based on a condition within the AbcDialog.ts file? Thank you! ...

Encountering an issue while attempting to import the react-autosuggest module, receiving the following error

I recently encountered an issue while trying to import the react-autosuggestion module in my TypeScript file on Ubuntu v18 OS. Initially, I executed the following command: sudo npm install react-autosuggest --save import Autosuggest from 'react- ...

How to access type properties in typescript without using the "this" keyword

Below is a snippet of code that I am working with: class Player implements OthelloPlayer { depth; constructor(depth: number) { this.depth = depth; } getMove(state: OthelloState) { return this.MinimaxDecision(stat ...

Utilizing the Pub/Sub architecture to integrate the kafka-node library within Node Js

Utilizing the kafka-node module in my NodeJs Microservise project, I am aiming to implement a Pub/Sub (publisher and subscriber) design pattern within the Functional programming paradigm. producer.js const client = new kafka.KafkaClient({ kafkaHost: ...

Unable to access 'export default class extends Vue' in the template

I've recently started using Vue.js with TypeScript, but I'm having trouble accessing values from outside the class. @Component({ name: 'SidebarItem', components: { SidebarItemLink } }) export default class extends ...

Creating a Loading Sign with a Button Component in React

Request Description: In my form, I have a button that triggers a submission to the backend. While the request is processing, I want the button to display a loading indicator instead of the usual text. Once the request is complete, I need the form to disap ...

Error message: TscToolPath is missing in the Microsoft.TypeScript.targets file following the installation of Visual Studio 2015 update 3

Encountering an error in Visual Studio 2015 after updating to version 3 and using TypeScript 2.0. Error Invalid command line switch for "tsc.exe". Value cannot be null. Parameter name: path1 ProjectTest C:\Program Files (x86)\MSBuild&bso ...

Tips for locating precise information within nested object formations using Javascript

Within my code, I have showcased two distinct types of response. Upon closer examination of the following code snippets, it becomes evident that the structure of the response from a service differs slightly between the two types. In the first type, there i ...

What is the process for obtaining an HTML form, running it through a Python script, and then showcasing it on the screen

I am inquiring about the functionality of html and py script. .... The user enters 3 values for trapezoidal data from the html form: height, length of side 1, and length of side 2, then clicks submit. The entered values are then sent to be calculated using ...

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 ...

What is the process of destructuring an array containing objects?

Examining this JSON structure: { "Person": { "UID": 78, "Name": "Brampage", "Surname": "Foo" }, "Notes": [ { "UID": 78, "DateTime": "2017-03-15T15:43:04.4072317", "Person": { ...

Tips for capturing an event from a bespoke button component integrated within an ng2-smart-table

Currently, my task involves triggering an event in Angular2 by clicking a button within a child component that is displayed within a ng2-smart-table located in the parent component as a column. Unfortunately, I am facing the challenge that I cannot add a ...

Typescript Error: Issue encountered while passing props. Unable to access properties as they are undefined

I encountered an issue where I created an object of a certain type and attempted to pass it to a component. However, when passing the props, I received an error message stating that it cannot read properties of undefined ('stepOne'). The error sp ...