- Typescript стрелочные функции generic
- # Table of Contents
- # Using generics in Arrow functions in TypeScript
- # Applying constraints around generics in arrow functions
- # Using generics in arrow functions in classes
- # When working in .tsx files, use a trailing comma
- # Additional Resources
- TypeScript — generic arrow function
- More complex example
- How To Make An Arrow Function Generic In TypeScript?
- Making an arrow function generic
- Making an arrow function generic in a .tsx file
- Final thoughts
- Generic Arrow Functions
- An example
- Extends trick
- Comma trick
- Just use a regular function
- Did you find this post useful?
Typescript стрелочные функции generic
Last updated: Jan 24, 2023
Reading time · 3 min
# Table of Contents
# Using generics in Arrow functions in TypeScript
You can use a generic in an arrow function by setting it right before the function’s parameters.
The generic can be passed when the function is invoked.
Copied!const returnInArray = T,>(value: T): T[] => return [value]; >; const strArray = returnInArraystring>('bobbyhadz.com'); const numArray = returnInArraynumber>(100);
Generics allow us to pass types as a variable to functions and classes.
The syntax for calling a function that has a generic is the same — it’s passed right before the function’s arguments.
Note that we didn’t have to explicitly provide the generic when calling the function.
In this situation, TypeScript would be able to infer the type of the generic based on the type of the passed-in argument.
Copied!const returnInArray = T,>(value: T): T[] => return [value]; >; // 👇️ const strArray: string[] const strArray = returnInArray('bobbyhadz.com'); // 👇️ const numArray: number[] const numArray = returnInArray(100);
# Applying constraints around generics in arrow functions
We can apply constraints around generics to only allow certain types to be passed.
Copied!type CanRun = run(): void; >; // 👇️ Can only be called with an object that has run() method const callRun = T extends CanRun>(obj: T) => obj.run(); >; // 👇️ the animal runs callRun( run: () => console.log('the animal runs') >); class Dog run() console.log('the dog runs'); > > callRun(new Dog()); // 👉️ the dog runs
The callRun arrow function can only be called with an object that has a property run that is a function with a return type of void .
If we try to call the function with a value that doesn’t satisfy the CanRun type, we would get an error.
Copied!type CanRun = run(): void; >; const callRun = T extends CanRun>(obj: T) => obj.run(); >; // ⛔️ Argument of type 'number' is not assignable // to parameter of type 'CanRun'.ts(2345) callRun(100);
This pattern is very commonly used when you need a guarantee that a function can only be called with an object that contains certain properties.
The object could be of multiple types, but as long as it contains the specified properties, it can be passed as an argument to the function.
Copied!class Shark swim() console.log('The shark swims'); > > class Dolphin swim() console.log('The dolphin swims'); > > interface CanSwim swim(): void; > const callSwim = T extends CanSwim>(obj: T): void => obj.swim(); >; callSwimDolphin>(new Dolphin()); callSwimShark>(new Shark());
The callSwim function takes an object parameter and calls the swim method on it.
The function uses a constraint to make sure that it only gets passed objects that contain a swim property of type function.
# Using generics in arrow functions in classes
You can also use generics in arrow functions in classes.
Copied!class GenericArray public arr: (string | number)[] = []; insert = T extends string | number>(el: T): void => this.arr.push(el); >; print = (): void => console.log(this.arr); >; > const ga1 = new GenericArray(); ga1.insertstring>('a'); ga1.insertnumber>(1); ga1.print(); // 👉️ ['a', 1] // ⛔️ Argument of type '< hello: string; >' is not assignable // to parameter of type 'string | number'.ts(2345) ga1.insert( hello: 'world' >);
The insert class method can either be passed a string or a number.
# When working in .tsx files, use a trailing comma
Notice that we used a trailing comma after the T type in the generic.
Copied!const returnInArray = T,>(value: T): T[] => return [value]; >; const strArray = returnInArraystring>('bobbyhadz.com'); const numArray = returnInArraynumber>(100);
Newer TypeScript compilers support a trailing comma after the last type in the generic.
This is necessary for .tsx files, otherwise, you’d get syntactical errors.
If you have multiple types, you don’t have to use a trailing comma in .tsx files, e.g. works.
Alternatively, you can extend an empty object if you still get syntactical errors in .tsx files.`
Copied!const returnInArray = T extends unknown>(value: T): T[] => return [value]; >; const strArray = returnInArraystring>('bobbyhadz.com'); const numArray = returnInArraynumber>(100);
The T extends unknown constraint does nothing and is only necessary if you get syntactical errors when working in .tsx files.
If you need to pass a function as a parameter, check out the following article.
# Additional Resources
You can learn more about the related topics by checking out the following tutorials:
I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
TypeScript — generic arrow function
maciek211
In this quick article, we are going to look at how to create generic arrow function in TypeScript.
The presented solution works for * .ts files — for * .tsx files, the problem solution is included in the Note under the first example.
const print = (entry: T) : void => < console.log(entry); >; print(100); // 100
const print = (entry: T) : void => < console.log(entry); >; print(true); // true
const print = (entry: T) : void => < console.log(entry.toText()); >; print('text'); // text
- the compiler automatically detects the argument type in the print function, so there is no needed type in the calls:
print(100); print(true); print('text');
const print = > (entry: T) : void => < /* code */ >
More complex example
In this example, we used a generic arrow function to iterate through an array. The iterate function takes an array and references to the iterating function. Both arguments are generic so we can work with array elements of different types.
interface Iteration < (index : number, item : T) : void; >const iterate = (array : Array, iteration : Iteration) : void => < for(let i = 0; i < array.length; ++i) < iteration(i, array[i]); >>; const array : Array = [ 1, 2, 3 ]; const iteration = (index : number, item : number) : void => < console.log(`$: $`); >; iterate(array, iteration);
How To Make An Arrow Function Generic In TypeScript?
Sometimes, a TypeScript developer wants to make an arrow function accept different types. That’s where generic functions come into play.
To make an arrow function generic, you need to add a generic parameter to it like this:
typescriptconst getX = (x: T) => x;
This article shows how to make an arrow function generic in TypeScript with many code examples.
In TypeScript, generics allow developers to make a function, class, or type work with any data type (without restricting it to one type). In short, it makes it simple to write reusable code.
Making an arrow function generic
To make an arrow function generic, you must pass a generic argument before the function parameters.
Let’s see this with an example.
We have a small function called getValue that accepts a number and outputs it:
typescriptconst output = (value: number): void => < console.log(value); >; // Outputs: 2 output(2);
This function only accepts numbers, but what if we want it to accept other types? We need to make it generic.
typescriptconst output = (value: T): void => < console.log(value); >; // Outputs: 2 outputnumber>(2); // Outputs: 'value' outputstring>('value');
The getValue function is now generic and accepts any argument type you pass.
If you want to limit the type of argument this function accepts, you need to add a generic constraint.
typescriptinterface IAnimal < type: string; eat: () => void; > class Dog implements IAnimal < type = 'dog'; eat(): void < console.log('eating') > > const output = extends IAnimal>(value: T): void => < console.log(value); >; // Outputs: Dog output(new Dog());
This function now only accepts an argument that implements the IAnimal interface.
The best Web Development course in 2023! 👉 Learn Web Development
Making an arrow function generic in a .tsx file
To make a generic TypeScript function work in .tsx files, you can add a comma after the last generic parameter.
typescriptconst output = (value: T): void => < console.log(value); >;
Or, you can add a generic constraint, for example:
typescriptconst output = extends unknown>(value: T): void => < console.log(value); >;
Both solutions work, but the first one is clearer.
Final thoughts
As you can see, making an arrow function generic is simple in TypeScript.
Simply add the generic parameters before the function parameters and use those generic types in the function definition.
Here are some other TypeScript tutorials for you to enjoy:
The best Web Development course in 2023! 👉 Learn Web Development
Hello! I am Tim Mouskhelichvili, a Freelance Developer & Consultant from Montreal, Canada. I specialize in React, Node.js & TypeScript application development. If you need help on a project, please reach out, and let’s work together.
Generic Arrow Functions
In this post, we cover how arrow functions with generic parameters can be implemented. It’s not as straightforward as we might think.
An example
Consider the generic arrow function below:
const firstOrNull = T>( arr: T[] ): T | null => arr.length === 0 ? null : arr[0];
This is a strongly-typed function that returns the first item in an array or null if it is empty.
This code is problematic though:
If we look at the transpiled code, we get a clue as to what the problem is:
The angle brackets are being confused with a JSX element!
Extends trick
In order to resolve the error, we need to help the transpilation process treat angle brackets as generic parameters. One way to do this is to add a constraint:
const firstOrNull = T extends unknown>( arr: T[] ): T | null => arr.length === 0 ? null : arr[0];
We extend from unknown because every type is assignable to unknown . The any type could also be used, but this isn’t type-safe.
Comma trick
Another trick is to add a comma after the generic parameter:
const firstOrNull = T,>( arr: T[] ): T | null => arr.length === 0 ? null : arr[0];
This is the syntax for defining multiple parameters and doesn’t error, even though we haven’t defined two parameters. This is enough for the transpilation process to treat the angle brackets as generic parameters.
Just use a regular function
Arguably the simplest solution is to use a regular function as opposed to an arrow function:
function firstOrNullT>(arr: T[]): T | null return arr.length === 0 ? null : arr[0]; >
It works like a treat and no tricks!
Did you find this post useful?
If you to learn more about using TypeScript with React, you may find my course useful: