window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster already exists') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Generics in TypeScript - The Codest
The Codest
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Industries
    • Fintech & Banking
    • E-commerce
    • Adtech
    • Healthtech
    • Manufacturing
    • Logistics
    • Automotive
    • IOT
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
Back arrow GO BACK
2020-05-26
Software Development

Generics in TypeScript

Mateusz Staniuk

Generics provide reusable bits of code that work with a number of types instead of a single type. Generics provide a way to treat type as a variable and specify it on usage, similar to function parameters.

Generics can be used in conjunction with functions (creating generic function), classes (creating generic class), and interfaces (creating generic interface).

Basic usage

You have probably used generics in the past even without knowing that – the most common usage of generics is declaring an array:

const myArray: string[];

It’s not too special at first glance, we just declaring myArray as an array of strings, but it is the same as a generic declaration:

const myArray: Array<string>;

Keepin’ things explicit

Let’s start with very simple example – how could we port this vanilla JS function to TypeScript:

function getPrefiledArray(filler, length) {
    return (new Array(length)).fill(filler);
}

This function will return array filled with given amount of filler, so length will be number and whole function will return array of filler – but what is filler? At this point it can be anything so one option is to use any:

function getPrefiledArray(filler: any, length: number): any[] {
    return (new Array(length)).fill(filler);
}

Using any is certainly generic – we can pass literally anything, so “work with a number of types instead of a single type” from the definition is fully covered, but we lose the connection between filler type and the return type. In this case, we want to return some common thing, and we can explicitly define this common thing as type parameter:

function getPrefiledArray<T>(filler: T, length: number): T[] {
    return (new Array(length)).fill(filler);
}

and use like this:

const prefilledArray = getPrefiledArray<number>(0, 10);

Generic Constraints

Let’s look at different, probably more common cases. Why do we actually use types in functions? For me, it is to ensure that arguments passed to the function will have some properties that I want to interact with.

Once again let’s try to port simple vanilla JS function to TS.

function getLength(thing) {
    return thing.length;
}

We have a nontrivial conundrum – how to ensure that the thing has a length property, and first thought may be to do something like:

function getLength(thing: typeof Array):number {
    return thing.length;
}

and depending on the context it might be correct, overall we are a bit generic – it’ll work with arrays of multiple types, but what if we don’t really know if the thing should always be an array – maybe the thing is a football field or a banana peel? In this case, we have to collect the common properties of that thing into a construct that can define properties of an object – an interface:

interface IThingWithLength {
  length: number;
}

We can use IThingWithLength interface as type of the thing parameter:

function getLength(thing: IThingWithLength):number {
    return thing.length;
}

quite frankly in this simple example, it’ll be perfectly fine, but if we want to keep this type generic, and not face the issue from the first example we can use Generic Constraints:

function getLength<T extends IThingWithLength>(thing: T):number  {
    return thing.length;
}

and use it:

interface IBananaPeel {
  thickness: number;
  length: number;
}

const bananaPeel: IBananaPeel = {thickness: 0.2, length: 3.14};
getLength(bananaPeel);

Using extends ensures that T will contain properties that are defined by IThingWithLength.

Generic Classes

Up to this point, we were working with generic functions, but it’s not the only place where generics shine, let’s see how can we incorporate them into classes.

First of all let’s try to store bunch of bananas in the bananas basket:

class Banana {
  constructor(
    public length: number,
    public color: string,
    public ionizingRadiation: number
  ) {}
}

class BananaBasket {
  private bananas: Banana[] = [];

  add(banana: Banana): void {
    this.bananas.push(banana);
  }
}

const bananaBasket = new BananaBasket();
bananaBasket.add(new Banana(3.14, ‘red’, 10e-7));

Now let’s try to create general purpose basket, to different stuff with the same type:

class Basket<T> {
  private stuff: T[] = [];

  add(thing: T): void {
    this.stuff.push(thing);
  }
}

const bananaBasket = new Basket<Banana>();

And lastly, let’s assume that our basket is a radioactive material container and we can only store matter that has ionizingRadiation property:

interface IRadioactive {
  ionizingRadiation: number;
}

class RadioactiveContainer<T extends IRadioactive> {
  private stuff: T[] = [];

  add(thing: T): void {
    this.stuff.push(thing);
  }
}

Generic Interface

Lastly let’s try to gather all our knowledge and build radioactive empire also using Generic Interfaces:

// Define common attributes for containers
interface IRadioactive {
  ionizingRadiation: number;
}


// Define something that is radioactive
interface IBanana extends IRadioactive {
  length: number;
  color: string;
}

// Define something that is not radioactive
interface IDog {
  weight: number;
}

// Define interface for container that can hold only radioactive stuff
interface IRadioactiveContainer<T extends IRadioactive> {
  add(thing: T): void;
  getRadioactiveness():number;
}

// Define class implementing radioactive container interface
class RadioactiveContainer<T extends IRadioactive> implements IRadioactiveContainer<T> {
  private stuff: T[] = [];

  add(thing: T): void {
    this.stuff.push(thing);
  }

  getRadioactiveness(): number {
      return this.stuff.reduce((a, b) => a + b.ionizingRadiation, 0)
  }
}

// ERROR! Type 'IDog' does not satisfy the constraint 'IRadioactive'
// And it’s kinda brutal to store dogs inside radioactive container
const dogsContainer = new RadioactiveContainer<IDog>();

// All good fam!
const radioactiveContainer = new RadioactiveContainer<IRadioactive>();

// Remember to sort your radioactive waste - create separate bin for bananas only
const bananasContainer = new RadioactiveContainer<IBanana>();

That’s all folks!

Related articles

Software Development

Build Future-Proof Web Apps: Insights from The Codest’s Expert Team

Discover how The Codest excels in creating scalable, interactive web applications with cutting-edge technologies, delivering seamless user experiences across all platforms. Learn how our expertise drives digital transformation and business...

THECODEST
Software Development

Top 10 Latvia-Based Software Development Companies

Learn about Latvia's top software development companies and their innovative solutions in our latest article. Discover how these tech leaders can help elevate your business.

thecodest
Enterprise & Scaleups Solutions

Java Software Development Essentials: A Guide to Outsourcing Successfully

Explore this essential guide on successfully outsourcing Java software development to enhance efficiency, access expertise, and drive project success with The Codest.

thecodest
Software Development

The Ultimate Guide to Outsourcing in Poland

The surge in outsourcing in Poland is driven by economic, educational, and technological advancements, fostering IT growth and a business-friendly climate.

TheCodest
Enterprise & Scaleups Solutions

The Complete Guide to IT Audit Tools and Techniques

IT audits ensure secure, efficient, and compliant systems. Learn more about their importance by reading the full article.

The Codest
Jakub Jakubowicz CTO & Co-Founder

Subscribe to our knowledge base and stay up to date on the expertise from the IT sector.

    About us

    The Codest – International software development company with tech hubs in Poland.

    United Kingdom - Headquarters

    • Office 303B, 182-184 High Street North E6 2JA
      London, England

    Poland - Local Tech Hubs

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warsaw, Poland

      The Codest

    • Home
    • About us
    • Services
    • Case Studies
    • Know How
    • Careers
    • Dictionary

      Services

    • It Advisory
    • Software Development
    • Backend Development
    • Frontend Development
    • Staff Augmentation
    • Backend Developers
    • Cloud Engineers
    • Data Engineers
    • Other
    • QA Engineers

      Resources

    • Facts and Myths about Cooperating with External Software Development Partner
    • From the USA to Europe: Why do American startups decide to relocate to Europe
    • Tech Offshore Development Hubs Comparison: Tech Offshore Europe (Poland), ASEAN (Philippines), Eurasia (Turkey)
    • What are the top CTOs and CIOs Challenges?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Copyright © 2025 by The Codest. All rights reserved.

    en_USEnglish
    de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek en_USEnglish