Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the difference between generic Type(T) vs any in typescript

What is the difference between generic Type(T) vs any in typescript?

Function 1

function identity(arg: any): any {     return arg; } 

Function 2

function identity<T>(arg: T): T {     return arg; } 

Function 3

function identity<T>(arg: T[]): T[] {     return arg; } 

Function 1 & 3 is accepted if we passing any kind of data type, But the function 2 does not accept if we pass an array. generic type is accepting all kind of data type on compile time. but here why it does not accept?

Also which function is good for better performance ( function 1 or function 3)?

like image 779
Ramesh Rajendran Avatar asked May 17 '17 11:05

Ramesh Rajendran


2 Answers

There is no difference if this is identity function that just returns an argument and used without type restrictions:

const foo: any = fn(['whatever']); 

And there is a difference for typed code:

const foo: string = fn('ok'); const bar: string = fn([{ not: 'ok' }]); 

Also, the usage of generic type provides semantics. This signature suggests that the function is untyped and returns anything:

function fn(arg: any): any { ... } 

This signature suggests that the function returns the same type as its argument:

function fn<T>(arg: T): T { ... } 

Real functions are usually more meaningful than just return arg example. Generic type can benefit from type restrictions (while any obviously can't):

function fn<T>(arg: T[]): T[] {   return arg.map((v, i) => arg[i - 1]); } 

But the benefits become more obvious when the function is used in conjunction with other generic classes and generic functions (and eliminated if non-generics are involved):

function fn<T>(arg: T[]): T[] {   return Array.from(new Set<T>(arg)); } 

This allows to consistently maintain T type between input (argument) and output (returned value):

const foo: string[] = fn(['ok']); const bar: string[] = fn([{ not: 'ok' }]); 

There cannot be any difference in performance because TypeScript types exist only on design time.

like image 96
Estus Flask Avatar answered Sep 17 '22 15:09

Estus Flask


There is absolutely no performance difference while using any of those methods, because all of these fancy things are just Typescript sugars and is only for development.

All the type checking is only in compile time ( when Typescript is transpiling/transforming your code back to normal javascript, in your server ).

Either way, when your code is shipped to the user's browser, this is how it looks :

function identity(arg){     return arg; } 

But to explain the differences :

When using any you'll lose all type checking and safety checking that Typescript is offering, whereas, T behaves like a variable that will hold the Type that you don't know what it is going to be.

So

function identity<T>(arg: T): T {     return arg; } 

In above, we know that if identify accepts number , it will return number and so on, where as :


function identity(arg: any): any {     return arg; } 

But now, you don't know if arg and the returned value are the same type or not.


The other issue that T will solve is when you're creating a method inside a class and it's expecting an argument which you want to make sure that this method will only accept arguments with the same type of the class's constructor's argument when instantiated.

export class MyClass<T>{     myMethod(anotherArg:T){}  } 

So using above :

let str = "string"; let instance = new MyClass(str); instance.myMethod("other string") // will compile 

Where as :

let num = 32423423; let instance = new MyClass(num); instance.myMethod("other string") // won't compile 
like image 36
Milad Avatar answered Sep 18 '22 15:09

Milad