말하는 컴공감자의 텃밭

TypeScript - 호출, 인덱스 시그니처 본문

백엔드/TypeScript

TypeScript - 호출, 인덱스 시그니처

현콩 2024. 1. 24. 11:47
728x90

호출 시그니처

호출 시그니처란 함수의 매개변수와 반환 값의 타입을 모두 type으로 미리 선언하는 것이다.

 

장점은 아래와 같다.

 

  1. 오버로딩: TypeScript는 메서드 오버로딩을 지원하므로 각각 다른 매개 변수 유형을 사용하여 단일 함수에 대해 여러 호출 서명을 정의할 수 있다. 이를 통해 함수는 다양한 유형의 입력을 처리할 수 있어 함수 사용 방법에 유연성을 제공한다.
  2. 인터페이스 구현: 인터페이스를 사용하여 TypeScript에서 호출 시그니처를 정의하면 코드 전체에 특정 함수 형태를 적용할 수 있는 방법이다. 구조화되고 재사용 가능하며, 유연한 방법이 제공되어 유형 안전성, 가독성 및 유지 관리성이 향상된다. 또한 객체 지향 디자인 원칙에 잘 맞으며 외부 코드를 사용하여 테스트하고 작업하는 것이 보다 더 쉽다.
  3. 유형 안전성: 호출 시그니처는 매개변수 유형을 정의하고 함수와 메소드에 대한 반환 값을 정의하는 방법을 명시한다. 이는 유형 안전성을 강화하여 올바른 유형의 인수로 함수가 호출되고 반환 유형이 예상한 유형인지 확인하게 한다. 이런 장점은 오류를 컴파일 타임에서 부터 잡아낼 수 있다.
  4. 코드 가독성 및 유지 관리: 호출 시그니처를 사용하면 함수가 수행해야 하는 작업, 예상되는 인수 종류, 반환되는 내용을 더 쉽게 이해하기 좋다. 코드를 더 읽기 쉽고 유지 관리하기 쉽게 만들어주기 때문에 대규모 코드베이스나 팀으로 작업할 때 효율적이다.

 

*오버로딩? : https://hb-in99.tistory.com/114

 

TypeScript - 함수 오버로딩

오버로딩 동일한 이름에 매개 변수만 다른 여러 함수를 만드는 것을 함수의 오버로딩이라고 한다. 바로 예제로 정리해보자 예제 1 add 라는 이름의 함수에 하나는 string, 하나는 number이다. function a

hb-in99.tistory.com

 


add라는 메서드에 호출 시그니처를 사용한 예시

const add = (a: number, b: number) => a + b

 

type Add = ( a: number, b: number) => number; // 호출 시그니처

const add: Add = (a, b) => a + b


interface를 활용하는 예제를 살펴보자.
먼저 like라는 숫자 매개변수를 리턴하는 객체 post1을 만들어 주었다.

const post1 = {
    id: 1,
    title: 'post 1',
    getLikeNumber(like: number) {
        return like
    }
}

 

post1을 위한 타입인 interface Post도 만들어 주었다.

interface Post {
    id: number;
    title: string;
    getLikeNumber: (like: number) => number;
}

 

 이 상황에서 getLikeNumber 메서드의   (like: number) => number  타입을 재사용하고자 한다면

interface getLikeNumber {

}

 

라는 인터페이스를 만들고, 메서드에 넣어준다면 재사용할 수 있다. 

post1에도 인터페이스를 적용하고, 확인해보면

post1.getLikeNumber(1);

 

호출 시그니처가 없다는 에러메세지가 나오게 된다.

getLikeNumber 인터페이스에 호출시그니처를 추가해줄건데

interface getLikeNumber {
// 형식 -> 소괄호 (매개변수: 타입) : 반환하는 타입
    (like: number): number;
}

 

메서드를 위한 타입을 넣어주면 된다.

 


인덱스 시그니처

유형 안전성과 일관성을 유지하기 위해 사용된다.

유연하고 동적이거나 객체 생성 후 프로퍼티를 추가하는 경우에 어떤 데이터가 올지 모를때 활용된다.

{[key : T] : U}형식으로 객체가 여러 Key를 가질 수 있으며 Key와 매칭되는 value를 가지는 경우 사용한다.

 

장점은 아래와 같다.

 

동적 속성 처리: 인덱스 시그니처를 사용하면 키를 미리 알 수 없는 속성으로 개체를 정의할 수 있으므로 동적이거나 유연한 데이터 구조에 적합하다.

 

사전과 같은 구조 생성: 특정 유형의 키를 기반으로 값을 조회할 수 있는 사전 또는 맵과 같은 객체를 생성할 수 있다.

 

동적 데이터에 대한 유형 안전성: 인덱스 시그니처는 객체가 보유할 수 있는 값 유형을 지정하여 API의 데이터와 같은 동적 데이터를 처리하는 데 유용하며, 데이터의 정확한 모양이 다음과 같은 경우에도 유형 안전성이 보장된다.

 

값 유형의 일관성: 인덱스 서명을 사용하면 개체의 모든 속성이 동일한 유형의 값을 갖도록 강제하여 개체 속성 전반에 걸쳐 일관성을 유지할 수 있다.

 

 

예제

post1라는 객체를 인터페이스 Post를 통해 타입을 정해주었다.

interface Post {
    id: number;
    title: string;
}

const post1: Post = {
    id: 1,
    title: 'post 1',
}

 

이후 기존 타입이외의 값이 들어온다면

 

오류를 발생시킨다.

이럴때 인덱스 시그니처가 활용되는데

interface Post {
// 추가할 속성 -> 대괄호 [ key : 타입 ] : 값의 타입
    [key: string]: unknown;
    id: number;
    title: string;
}

 

값의 타입은 무엇이 들어올지 몰라 unknown으로 주어진 모습니다.

 

any도 가능할거라 생각이 됩니다.

하지만 any는 정적 유형 검사의 이점을 무효화하므로 unknown이 낫겠군요!

 

만약 배열이라면?

interface Names {
// 인덱스 값이므로  key의 속성은 number로 된다.
    [item: number]: string;
}

 

const userNames: Names = ['John', 'kim', 'Joe']

 

 

참고 

https://www.typescriptlang.org/docs/handbook/2/functions.html

인프런 : https://www.inflearn.com/ 따라하며 배우는 타입스크립트 A-Z

728x90

'백엔드 > TypeScript' 카테고리의 다른 글

TypeScript - 함수 오버로딩  (1) 2024.01.24
Typescript - Type  (0) 2024.01.22
Comments