본문 바로가기
Web/JavaScript

[TypeScript] Generic

by llHoYall 2021. 7. 5.

Generic can create a component that can work over a variety of types rather than a single one.

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

This generic function is the same as below.

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

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

...

 

The T in the generic allows us to capture the type the user provides so that we can use that information later.

It doesn't lose any information unlike using any.

 

We can call the generic function like this.

let ret1 = identity<string>("test");  // Explicitly set
let ret2 = identity(7);  // Type inference

 

We can also apply the Generic in arrays.

function identityArray1<T>(arg: T[]): T[] {
  console.log(arg.length);
  return arg;
}

function identityArray2<T>(arg: Array<T>): Array<T> {
  console.log(arg.length);
  return arg;
}

identityArray1([1, 2, 3]);
// 3

identityArray2(['apple', 'banana']);
// 2

Generic Types

The type of generic functions is just like those of non-generic functions, with the type parameters listed first, similarly to function declarations.

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

let identityFunc: <T>(arg: T) => T = identity;

We can also write the generic type as a call signature of an object literal type.

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

let identityFunc: { <T>(arg: T): T } = identity;

We can apply interface in this example.

interface IGenericIdentityFn {
  <T>(arg: T): T;
}

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

let identityFunc: IGenericIdentityFn = identity;

We can move the generic parameter to be a parameter of the whole interface.

interface IGenericIdentityFn<T> {
  (arg: T): T;
}

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

let identityFunc: IGenericIdentityFn<number> = identity;

Generic Class

A generic class has a similar shape to a generic interface.

class GenericNumber<T> {
  // static test: T;  => Static members cannot reference class type parameters
  initialValue: T;

  constructor(_initialValue: T) {
    this.initialValue = _initialValue;
  }
}

let genericAdder = new GenericNumber<number>(0);

Generic classes are only generic over their instance side rather than their static side, so when working with classes, static members can not use the class's type parameter.

Generic with Object

We can declare a type parameter that is constrained by another type parameter.

function getValue<T, K extends keyof T>(object: T, key: K): T[K] {
  return object[key];
}
const obj = {
  name: "HoYa",
  age: 18,
};

const obj2 = {
  key: true,
};

console.log(getValue(obj, "name"));
console.log(getValue(obj, "age"));
console.log(getValue(obj2, "key"));

Default Type of Generic

We can assign a default value to the Generic.

class Data1<T = any> {
}

class Data2<T = {}> {
}

'Web > JavaScript' 카테고리의 다른 글

[TypeScript] Indexed Access Types, Mapped Types, Conditional Types  (0) 2021.07.09
[TypeScript] Mixins  (0) 2021.07.09
[TypeScript] Singleton Pattern  (0) 2021.07.05
[TypeScript] Class  (0) 2021.07.04
[TypeScript] Basic Types  (0) 2021.07.04

댓글