Skip to content

Instantly share code, notes, and snippets.

@DublinCity
Last active June 28, 2022 17:09
Show Gist options
  • Save DublinCity/6cb79555f924df9d6789db10f249a94c to your computer and use it in GitHub Desktop.
Save DublinCity/6cb79555f924df9d6789db10f249a94c to your computer and use it in GitHub Desktop.
# Item50: 오버로딩 타입보다 조건부 타입 사용하기

Item50: 오버로딩 타입보다 조건부 타입 사용하기

간단하게 numberstring 타입의 매개변수를 받아 두개를 더하는 함수를 생각해보자

시도 1

호기롭게 아래와 같이 작성해본다.

function double(input: string|number): string|number {
    return input+input // type error
}

그리고 나선 input + input 부분에서 타입에러가 나는것을 볼 수 있다.

오버로딩으로 해결 1(유니온 이용)

아래는 선언이 틀린 것은 아니지만 함수로 사용시 모호한 부분이 생긴다.

function double(input: string|number): string|number
function double(input: any): any {
    return input+input
}

const a = double(1) // string|number
const b = double('1') // string|number

오버로딩으로 해결 2(제네릭 이용)

아래와 같이 제네릭으로 해결해보는 시도는 좋았지만, 너무 과하다. 리터럴 타입이 인자로 왔을때 기대하지 못한 값이 리턴타입이 된다

function double<T extends string|number>(input: T): T
function double(input: any): any {
    return input+input
}

const a = double(1) // number
const b = double('1') // '1'

오버로딩으로 해결 3(어려가지 타입선언으로 분리)

아래와 깉이 타입선언을 분리하면 구체적으로 사용할 수 있다.

function double(input:string):string
function double(input:number):number
function double(input: any): any {
    return input + input
}

하지만 버그가 있다!

string 이나 number 값으로는 잘 동작하지만, 유니온 타입관련해서 문제가 발생한다.

function f(input: string|number) {
    return double(input) // type error
}

오버로딩으로 해결 4(유니온 타입을 오버로딩)

아래처럼 해결할 수도 있다.

function double(input:string):string
function double(input:number):number
function double(input:string|number):string|number
function double(input: any): any {
    return input + input
}

조건부 타입 사용하기

가장 좋은 해결책은 조건부 타입을 사용하는 것이다.

function double<T extends string|number>(input: T): T extends string ? string : number
function double(input:any):any {
    return input + input
}

유니온에 조건부 타입을 적용하면, 조건부 타임의 유니온으로 분리된다

(number|string) extends string ? string : number
-> (number extends string ? string : number) | (string extends string ? string : number)
-> number | string

결론

  • 오버로딩 타입이 작성하기는 쉽지만, 조건부 타입은 개별타입의 유니온으로 일반화하기 때문에 타입이 더 정확해진다.
  • 타입 오버로딩이 필요한 경우에 조건부 타입을 사용해서 개선할 수 있을 지 검토하자.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment