[typescript] Generics

Suyeon·2020년 11월 12일
0

Typescript

목록 보기
8/12

Built in generics

const names: Array<string> = []; // string[]
names[0].split(' ');

// Promise
const promise: Promise<number> = new Promise((resolve, reject) => {
   setTimeout(() => {
      resolve('It is done!');
   }, 2000);
});

promise.then(data => {
   console.log(data);
});

Generic Function

creating reusable components is generics, that is, being able to create a component that can work over a variety of types rather than a single one. This allows users to consume these components and use their own types.

  • Type variable, a special kind of variable that works on types rather than values. This T allows us to capture the type the user provides, so that we can use that information later.
/*
function mergeFunc(objA: object, objB: object) {
   return Object.assign(objA, objB);
}

const mergedObj = merge({ name: 'Suyeon', age: 25 });
console.log(mergedObj.age); // Not working!

(*) mergeFunc returns object & object = unknown object.
Ts doesn't know additional informations about returned object.
*/

// Example 1️⃣ 
function mergeFunc<T, U>(objA: T, objB: U) { // (*) it can be any type.
   return Object.assign(objA, objB); 
}

const mergedObj = merge({ name: 'Suyeon'}, { age: 25 });
console.log(mergedObj.age);

// Example 2️⃣
function identity<T>(arg: T): T {
  return arg;
}

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

Constraints

  • Specify which type generic type should be.
  • extends keyword
// "T" and "U" can be any object but it should be an object.
function mergeFunc<T extends object, U extends object>(objA: T, objB: U) { 
   return Object.assign(objA, objB); 
}

const mergedObj = merge({ name: 'Suyeon' }, 30); // Not working!

keyof

You can declare a type parameter(keyof) that is constrained by another type parameter. We’d like to ensure that we’re not accidentally grabbing a property that does not exist on the obj.

// "U" should be property of "T".
function extractAndConvert<T extends object, U extends keyof T>(
  obj: T, key: U
) {
   return obj[key];
}

extractAndConvert({ name: 'Suyeon'}, 'name');
extractAndConvert({ name: 'Suyeon'}, 'age'); // Not working!

Generic Classes

We don't care about type of item property.

class DataStorage<T extends string | number | boolean> {
  private data: T[] = [];

  addItem(item: T) {
     this.data.push(item);
  }

  removeItem(item: T) {
     this.data.splice(this.data.indexOf(item), 1);  
  }

  getItems() {
     return [...this.data];
  }
}

const textStorate = new DataStorage<string>();
textStorage.addItem('Suyeon');

const numberStorate = new DataStorage<number>();
numberStorate.addItem(25);

Generic Utility Types

// Readonly
const names: Readonly<string[]> = ['Suyeon', 'Hanna'];
names.push('Sarang'); // Not working!
profile
Hello World.

0개의 댓글