본문 바로가기
반응형

Call Signature

함수의 타입을 정의하는 방법 중 하나로, Call Signature는 함수가 어떤 매개변수를 받아 어떤 타입의 값을 반환하는지 명확히 설명해준다. 이는 인터페이스 또는 타입 별칭을 사용하여 정의할 수 있도록 도와준다.

 

Call Signature의 장점

  1. 명확한 타입 정의: 함수의 입력과 출력 타입을 명확히 정의하여, 함수 사용 시 타입 안전성을 보장한다.
  2. 코드 재사용성: 동일한 시그니처를 가진 여러 함수를 정의할 때 일관성을 유지할 수 있다.
  3. 타입 체크: 함수 타입을 미리 정의함으로써, 함수 호출 시 올바른 타입의 매개변수를 전달하도록 강제할 수 있다.
// 함수 타입 별칭 'Multiply'를 정의, 
// 이 타입은 두 개의 숫자 매개변수를 받아 숫자를 반환하는 함수 타입을 나타낸다.
type Multiply = (x: number, y: number) => number;

// 'multiply'라는 함수를 'Multiply' 타입으로 선언
// 이 함수는 두 개의 숫자 매개변수를 받아 두 숫자의 곱을 반환
const multiply: Multiply = (x, y) => x * y;

Overloading(오버로딩)

동일한 함수 이름으로 여러 가지 호출 시그니처(Call Signature)를 정의하는 기능을 말하며, 이를 통해 함수가 다양한 입력을 받을 수 있도록 하고, 각 입력에 따라 다른 동작을 수행할 수 있게 한다. 오버로딩은 주로 복잡한 함수 동작을 정의할 때 사용됩니다.

 

오버로딩의 장점

  1. 유연성: 함수가 다양한 입력을 받을 수 있도록 하여, 더 유연한 코드를 작성할 수 있다.
  2. 가독성: 함수의 여러 호출 시그니처를 정의함으로써, 함수 사용 방법을 명확히 알 수 있다.
  3. 타입 안전성: 각 호출 시그니처에 대해 타입 검사를 수행하므로, 타입 안전성을 보장받을 수 있다.

오버로딩 예시
add  함수가 두 가지 형태로 호출될 수 있음을 나타낸다.
오버로딩 예시코드 2
매개변수  config 가 문자열인지,  Config  객체인지에 따라 다른 동작을 수행하게 된다.

다형성(Polymorphism)과 제네릭(Generics)

Polymorphism (다형성)

다형성은 객체 지향 프로그래밍의 핵심 개념 중 하나로, 여러 형태를 가질 수 있는 능력을 의미한다. TypeScript에서는 함수나 클래스를 다양한 타입으로 사용할 수 있게 함으로써 다형성을 구현할 수 있는데. 즉, 동일한 함수가 다양한 타입의 인자를 처리할 수 있는 것을 말한다.

 

Generics (제네릭)

제네릭은 타입을 매개변수로 사용할 수 있는 기능을 말하며, 이는 함수, 클래스 또는 인터페이스가 다양한 타입에서 작동할 수 있게 하여 코드의 재사용성과 타입 안전성을 높일 수 있다. 제네릭을 사용하면 타입을 미리 정하지 않고, 함수나 클래스가 호출될 때 타입을 지정할 수 있다.

 

Polymorphism과 Generics의 장점

  1. 재사용성: 제네릭을 사용하면 타입에 독립적인 코드를 작성할 수 있어, 코드의 재사용성이 높아진다.
  2. 타입 안전성: 제네릭을 사용하면 컴파일 시점에 타입을 검사할 수 있어, 런타임 오류를 줄이고 타입 안전성을 높일 수 있다.
  3. 유연성: 제네릭은 다양한 타입을 처리할 수 있는 유연한 코드를 작성할 수 있게 도와준다.

다형성(Polymorphism)과 제네릭(Generics) 예시 코드
superPrint  함수는 호출될 때마다 전달된 배열의 타입에 따라  T  타입이 결정된다.

더보기

왜 any로 설정하지 않고 Generics을 사용할까?

any와 재너릭의 차이
any  타입은 모든 타입을 허용하지만, 타입 검사 기능을 무력화하게 된다. 그렇기에 any 를 사용하면 타입 안전성이 떨어지고, 예기치 않은 오류가 발생할 수 있다.

Generics(제네릭)의 확장

// 제네릭 타입 'Player'를 정의하며 'E'는 제네릭 타입 매개변수로, 'extraInfo'의 타입을 정의하고 있다.
type Player<E> = {
    name: string;  // 모든 'Player' 객체는 'name' 프로퍼티를 가지며, 이는 문자열 타입을 요구한다.
    extraInfo: E;  // 'extraInfo' 프로퍼티는 제네릭 타입 'E'에 의해 정의된다.
}

// 'JkExtra' 타입을 정의한다.
// 'JkExtra'는 'favSports' 프로퍼티를 가지며, 이는 문자열 타입을 요구한다.
type JkExtra = {
    favSports: string;
}

// 'Player' 타입을 확장하여 'JkPlayer' 타입을 정의
// 'extraInfo'의 타입으로 'JkExtra' 타입을 사용한다.
type JkPlayer = Player<{ favSports: string }>;

// 'JkPlayer' 타입의 객체 'jk'를 생성,
// 이 객체는 'name'과 'extraInfo' 프로퍼티를 가집니다.
const jk: JkPlayer = {
    name: "정규",  // 'name' 프로퍼티는 문자열 타입으로 따르게 된다.
    extraInfo: {  // 'extraInfo' 프로퍼티는 객체이며, 'JkExtra' 타입을 따르게 된다.
        favSports: "soccer"  // 'favSports' 프로퍼티를 문자열 타입을 입력
    }
};

 

728x90
반응형