This module looks at Generics in Typescript, and how to create different types of generic Functions, Classes and Interfaces.
Learning Objectives
The objectives of this module are to provide you with an understanding of:
- How to create Generic Functions
- How to create Generic Classes
- How to create Generic Interfaces
Intended Audience
This learning path is aimed at all who wish to learn how to use TypeScript
Prerequisites
It is essential you understand the face of contemporary web development to attend this course. You should have a good working knowledge of Javascript.
Please note: Before attending this class delegates must have a Microsoft account (signing up for one is free).
Feedback
We welcome all feedback and suggestions - please contact us at qa.elearningadmin@qa.com to let us know what you think.
TypeScript can provide a special type variable identified by angle brackets. This can be one of the primitive types or a user defined type, such as a class. In general though, this type variable is denoted by T. The function shown on the right is generic. That's because it will work across a range of types, but unlike using the any type, it will retain its shape throughout the function. We can call the function stating the type that we are passing in by putting it in the angle brackets after the function name and before the arguments. This makes the call specific rather than inferred. The T variable can be of any type unless you constrain it. More on that soon. So, you need to be careful to treat it as such, otherwise you'll get errors. Why would the function shown possibly fail? The answer, not all types will have a property of length, so dependent on the type passed in, it may cause an error. Let's see an example of another generic function. Imagine we had a scenario where we collect data in an array. When it comes to processing the array, we want to reverse it and log it out. In the code, you can see two arrays of different types and two utility functions that perform the array reverse for the particular type. If you look at the code, the reversing functions are pretty much the same. In fact, the underlying JavaScript wouldn't care about the types we've applied. However, we are using TypeScript to help with the type safety of our code, and, in this instance, we want to reverse an array of any type. So, how many similar functions would we need to write to cover all types? And how could I write a single function in TypeScript that would perform this action with type safety? That's the job of generics. We've defined a function called reverseAnyArray to accept an array of any particular type. We use a special type variable identified in angle brackets. Type variables are represented conventionally by T. We then give the function an argument of any array that is typed as an array of type T. The function body defines a new array of type T, and performs the reverse function, and logs it out. When we call this function, if we ran this code, it would put the array back in the original state. Don't forget, the underlying JavaScript would ignore the generics, and any three of the functions would actually work if they were passed an array of any type. The point of using TypeScript is that, in our code, the compiler will check to see if what has been passed to the function is actually an array of a specific type without polluting the code with type checking and error handling. We can constrain the type parameter using another type parameter. This is useful when we're working with objects. Say we want to process an object by its keys. The object may be generic, so we'd like to constrain the keys to those in the object. We can use the extends keyof keyword combination to ensure that the second type K is actually a key of the type T. In the code shown, we have a function called getValueOfKey. The purpose of this function is to log out the value of a particular key in the generic object passed in T. We want to make sure that we only use a key parameter that's actually a property on the object passed in, so we constrain between the two types. We define a simple object on line five with some key value pairs. We then call our function with the object and key name we want to display. The fourth call on line 10 passes a key name that doesn't exist on the object, so TypeScript highlights that we have an error here. There's a second object defined on line 12, and the results of the function call on line 14 and 15. Now, height means an error. The function works with any object, with any key names. You might say it's generic. This makes working with the object passed in and its keys much more type safe, and less likely to produce an error whilst running in production. That's as long as you fix the TypeScript errors, of course.
Ed is an Outstanding Trainer in Software Development, with a passion for technology and its uses and holding more than 10 years’ experience.
Previous roles have included being a Delivery Manager, Trainer, ICT teacher, and Head of Department. Ed continues to develop existing and new courses, primarily in web design using: PHP, JavaScript, HTML, CSS, SQL, and OOP (Java), Programming Foundations (Python), and DevOps (Git, CI/CD, etc). Ed describes himself as practically minded, a quick learner, and a problem solver who pays great attention to detail.
Ed’s specialist area is training in Emerging Technologies, within Web Development. Ed mainly delivers courses in JavaScript covering vanilla JS, ES2015+, TypeScript, Angular, and React (the latter is authored by Ed) and has delivered on behalf of Google for PWAs. Ed has also developed a new suite of PHP courses and has extensive experience with HTML/CSS and MySQL.
Ed is responsible for delivering QA’s Programming Foundations course using the Eclipse IDE. His skillset extends into the DevOps sphere, where he is able to deliver courses based around Agile/Scrum practices, version control, and CI/CD.