DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Subtitles: The Good, the Bad, and the Resource-Heavy
  • Integrating Jenkins With Playwright TypeScript: A Complete Guide
  • Efficiently Migrating From Jest to Vitest in a Next.js Project
  • Implement a Geographic Distance Calculator Using TypeScript

Trending

  • A Modern Stack for Building Scalable Systems
  • Unmasking Entity-Based Data Masking: Best Practices 2025
  • Agile and Quality Engineering: A Holistic Perspective
  • AI’s Role in Everyday Development
  1. DZone
  2. Coding
  3. JavaScript
  4. TypeScript Basics: How Generic Types Work

TypeScript Basics: How Generic Types Work

Generic types let us define custom types when we use a type or function. Let's look at how generic types work in Typescript.

By 
Johnny Simpson user avatar
Johnny Simpson
DZone Core CORE ·
Updated Apr. 21, 22 · Tutorial
Likes (7)
Comment
Save
Tweet
Share
4.8K Views

Join the DZone community and get the full member experience.

Join For Free

Typescript generics are a way to take a function that has an argument that we can define when we call that argument - the same way we can change an argument of a function when we call it.

If you're new to the concept of Typescript generics, then read on to learn how they work.

How TypeScript Generics Work

Imagine a function like this the one below - it has an argument which is of type string, and it outputs a string on top of that:

TypeScript
 
let myFunction = function(arg: string):string {
    return `Hello, the value of your argument is ${arg}`;
}
// This will return "Hello, the value of your argument is World"

Interestingly, myFunction works both with a variety of types, such as a string, or number. When we make something work over a multitude of different circumstances, it's called a generic, and that's exactly what a Typescript generic is.

To adjust our Typescript function to become generic, we add a definable argument in <>s straight after the function keyword:

TypeScript
 
let myFunction = function<NewType>(arg: NewType):string {
    return `Hello, the value of your argument is ${arg}`;
}

// This will return "Hello, the value of your argument is World"
myFunction<number>(5);

Think of generic parameters in Typescript the same way as arguments in vanilla Javascript. In the example above, we've made a new argument, called NewType - but you can call it anything. Our argument, arg, is of type NewType.

Then, when we call myFunction(), we can define the type of our argument - in the case above, a number.

Generics With Multiple Types

Imagine another example, where we aren't using string literals - in the example below, we simply add our two arguments together:

TypeScript
 
let myFunction = function(x: string, y: string):string {
    return x + y;
}

// Returns HelloWorld
myFunction("Hello", "World");

Again, this works with multiple types - most notably strings and numbers. Let's try adding a generic type again:

TypeScript
 
let myFunction = function<NewType>(x: NewType, y: NewType):number {
    return x.length + y.length;
}

Except, this time, we'll get an error:

Plain Text
 
Property 'length' does not exist on type 'NewType'

The reason this throws an error is that we haven't defined what NewType can and can't do. To resolve this example, we simply have to mention that x and y will be an Array of NewTypes by using [] brackets:

TypeScript
 
let myFunction = function<NewType>(x: NewType[], y: NewType[]):number {
    return x.length + y.length;
}
// This will return 6 (3 + 3)
myFunction<number>([ 5, 6, 7 ], [ 10, 9, 8 ]);

Extending Generic Types

Sometimes, however, we have a different set of circumstances. We may have a situation where we want to extend NewType, for example, if we are accessing a property that NewType should have, but the compiler does not know about it. We can extend generic types using the extends keyword. That means we can constrain any types passed to our function, so they have a minimum set of properties.

In the below example, all elements of type NewType should have at least the property name:

TypeScript
 
type ExtendedNewType = {
    name: string
}

type User = {
    name: string,
    age?: number
}

// NewType must contain at least the attribute "name" - so lets add it as an extension of our ExtendedNewType type.
let myFunction = function<NewType extends ExtendedNewType>(x: NewType, y: NewType):string {
    return `${x.name} ${y.name}`
}
// This will return "Hello World"
let runFunction = myFunction<User>({ name: "Hello" }, { name: "World" });

Custom Types

We are defining custom types above. If you are new to custom types, try reading our guide on creating custom types in Typescript

Generic Custom Types

As well as applying generic types to our functions, we can also apply them to our own custom types. In the below example, we have a user where an ID may be a string or a number. We can define a generic type at the top level of our new type, and then define it whenever we use the User type.

TypeScript
 
// Type User can have an ID which is either a number or a string
type User<CustomType extends (number | string)> = {
    id: CustomType,
    name?: string,
    age?: number
}

// In this case, we define CustomType as a string
let myUser:User<string> = {
    id: "1234-1234-1234",
    name: "John Doe",
    age: 24
}

// In this case, we define CustomType as a number
let myOtherUser:User<number> = {
    id: 1234,
    name: "Jane Seymore",
    age: 48
}
TypeScript

Published at DZone with permission of Johnny Simpson, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Subtitles: The Good, the Bad, and the Resource-Heavy
  • Integrating Jenkins With Playwright TypeScript: A Complete Guide
  • Efficiently Migrating From Jest to Vitest in a Next.js Project
  • Implement a Geographic Distance Calculator Using TypeScript

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!