ReasonJun

Typescript : Generic 본문

Frontend/Typescript

Typescript : Generic

ReasonJun 2023. 6. 10. 14:37
728x90

Generics in TypeScript allow you to create reusable components or functions that can work with different types. They provide a way to define placeholders for types that are determined by the user of the component or function.

 

Generic types are defined using angle brackets (<>) and can be applied to classes, interfaces, functions, and type aliases. Here's an example of defining a generic function:

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

In the example above, identity is a generic function that takes an argument of type T and returns the same type T. The type parameter T acts as a placeholder for the actual type that will be provided when the function is called.

 

You can call the identity function with different types, and TypeScript infers the type based on the argument passed:

let result = identity<string>('Hello');
console.log(result); // Output: Hello

result = identity<number>(42);
console.log(result); // Output: 42


function toArray <T> (a: T, b: T) {
    return [a, b]
}

console.log(
    toArray('Neo', 'Anderson'), // ['Neo, 'Anderson']
    toArray<number>(1, 2), // This is also possible.
    toArray(true, false),
    toArray({ x:1 }, { y:2 }),
    toArray([1, 2], [3, 4, 5]), // number[] not tuple
    toArray<Arr>([1, 2], [3, 4, 5]) // error
)

In the first call, T is inferred as string because the argument passed is of type string. In the second call, T is inferred as number.

 

Generic types can also be used with interfaces and classes. Here's an example of a generic class:

class Stack<T> {
  private elements: T[] = [];

  push(element: T): void {
    this.elements.push(element);
  }

  pop(): T | undefined {
    return this.elements.pop();
  }
}




class UserP <P> {
    constructor(public payload: P) {}
    getPayload() {
        return this.payload
    }
}

interface UserAType {
    name: string
    age: number
    isValid: boolean
}

interface UserBType {
    name: string
    age: number
    emails: string[]
}

const heropyq = new UserP <UserAType> ({
    name: 'Heropy',
    age: 85,
    isValid: true,
    emails: [] // error
})

const neeo = new UserP <UserBType>({
    name: 'Neo',
    // Error occurs because there is no AGE
    emails: ['neo@gmail.com']
})


/// interface, Constraint

interface MyData<T extends string | number> {
  name: string;
  value: T;
}
const dataA: MyData<string> = {
  name: 'Data A',
  value: 123, // error
};

const dataB: MyData<number> = {
  name: 'Data A',
  value: 1234,
};

The Stack class is a generic class that represents a stack data structure. The type parameter T represents the type of elements stored in the stack. This allows the stack to work with different types of elements. You can create instances of the Stack class with different types:

const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
console.log(numberStack.pop()); // Output: 2

const stringStack = new Stack<string>();
stringStack.push('Hello');
stringStack.push('World');
console.log(stringStack.pop()); // Output: World

In the example above, numberStack is an instance of the Stack class with type parameter number, and stringStack is an instance with type parameter string.

 

Generics provide flexibility and reusability in TypeScript code by allowing you to write functions and classes that can work with multiple types. They enable you to create more generic and type-safe components that can adapt to different data types and provide compile-time type checking.

728x90

'Frontend > Typescript' 카테고리의 다른 글

Typescript : tsconfig.json  (0) 2023.06.10
Typescript : Module (CommonJS / ECMAScript Modules)  (0) 2023.06.10
Typescript : Class & Access Modifiers  (2) 2023.06.10
Typescript : Overloading  (0) 2023.06.10
Typescript : Explicit this  (0) 2023.06.10
Comments