함수 타입

김동현·2022년 4월 11일
0

TypeScript

목록 보기
6/18
post-thumbnail

Function

함수 타입의 경우 포함 관계는 아래와 같습니다.

포함 관계 : unknown > any > object > "Function" > any

함수 타입의 경우에도 Function혹은 구체적인 함수 구조를 타입으로 사용할 수 있습니다.

1. 함수 선언

매개변수 타입

타입스크립트에서는 함수의 각 매개변수에 타입을 지정할 수 있습니다. 이때 타입은 변수에 타입을 지정하는 방식처럼 작성해줍니다.

매개변수의 타입은 일반적으로 타입 범위를 "넓게 설정"합니다. 너무 구체적으로 설정하게 된다면 사용하는데 불편하게 됩니다.

만약 명시적으로 타입을 지정하지 않은 경우 any 타입으로 추론됩니다.

함수를 호출할 때 지정된 매개변수의 개수만큼만 인수를 전달받을 수 있으며 추가적으로 인수를 전달받지 않으며 덜 받지도 않습니다.

즉, 지정된 매개변수만큼 인수를 전달해주어야 하며, 각 인수는 매개변수에 지정된 타입의 값만 전달할 수 있습니다.


함수의 매개변수로 구조 분해 할당을 사용하는 경우 각 매개변수의 타입은 아래처럼 작성해주어야 합니다.

위 함수처럼 "{ 매개변수,,, }: { 매개변수: type,,, }" 형식으로 타입을 명시합니다.

반환값 타입

함수의 반환값의 경우 기본적으로 내부 return 문에 의해 타입 추론이 이루어집니다. 명시적으로 return 문을 작성하지 않은 경우에는 void 타입으로 추론됩니다.

반환값의 타입의 경우 타입 범위가 "구체적"이어야 합니다.

함수의 반환 타입을 명시하면 함수에 대해 더욱 명확하게 알 수 있으며, 반환되는 값의 타입이 복잡할 수록 타입을 명시하는 이점이 더 큽니다.

sum 함수의 반환값은 매개변수 a와 b를 더한 값입니다. 매개변수 a와 b는 number 타입이므로 반환값 또한 number 타입으로 추론됩니다.

sumToString 함수의 경우에는 매개변수 a, b는 number 타입을 갖지만, return 값에서 toString 메서드를 통해서 문자열을 반환하기 때문에 반환값 타입이 string 타입으로 추론됩니다.

2. Function

: Function 타입을 지정하면 함수의 구조와는 상관없이 어떤 함수 객체라도 할당받는 변수를 선언할 수 있습니다. 하지만 이는 타입스크립트에게 함수에 대한 정보를 제공하지 않기 때문에 매개변수 개수나 타입 검사 등 실시하지 않습니다.

3. 함수 시그니처

함수 타입을 정의할 때 화살표 함수처럼 함수 타입을 정의할 수 있습니다.

이때 소괄호에는 매개변수와 전달받을 인수 타입, 그리고 함수 반환값의 타입을 화살표 우변에 작성합니다.

func 변수는 두 개의 매개변수는 각각 number 타입의 값을 인수로 전달받고, 반환값이 number 타입인 함수를 할당받을 수 있습니다.


함수 시그니처로 작성한 매개변수 이름은 함수에 영향을 주지 않으며 "작성된 순서대로 매개변수 타입이 일치"해야 합니다.

함수 호출문

함수 호출문을 작성할 때 인수의 타입은 매개변수 타입과 일치해야 하며, 전달되는 인수의 개수도 선언한 매개변수의 개수와 일치해야합니다.

불필요하게 인수를 초과하여 전달하거나, 매개변수의 개수보다 적게 인수를 전달하는 경우 에러가 발생합니다.

즉, 매개변수의 개수와 전달하는 인수의 개수가 반드시 일치해야 하며, 전달되는 인수 타입이 매개변수 타입과 반드시 일치해야 합니다..

옵셔널 파라미터(?:)

함수는 지정된 매개변수의 개수 이외 추가적으로 인수를 전달받거나 적게 받을 수 없습니다.

만약 전달되는 인수의 개수가 상황에 따라 다르다면 "옵셔널 파라미터(?:)"를 사용하여 매개변수의 타입을 지정해줍니다.

log 함수는 첫 번째 인수가 반드시 전달되어야 하고, 이후 세 번째 인수까지는 전달되거나 전달되지 않아도 됩니다. 즉, 매개변수의 개수와 전달되는 인수의 개수가 상황에 따라 달라진다면 ?:로 매개변수의 타입을 지정합니다.

단, 인수를 하나도 전달하지 않거나, 네 개 이상 전달하는 경우에는 에러가 발생하게 됩니다.

this

타입스크립트에서 함수 내 this에 바인딩되는 객체의 구조 또한 명시적을 설정할 수 있습니다.

위 코드처럼 함수의 첫 번째 매개변수에 this를 작성하고 :뒤에 타입을 작성해줍니다. 반드시 this라는 이름으로 첫 번째 매개변수에 작성해주어야 합니다.

위 코드처럼 func 함수 내 this에 바인딩되는 객체의 구조는 user 변수의 객체 타입으로 지정됩니다.그리고 내부에서 this에 접근시 타입스크립트는 객체의 구조를 통해 접근가능한 프로퍼티나 메서드의 자동완성을 표시해주며 접근이 가능합니다. 이외 프로퍼티나 메서드에 접근시 에러를 표시합니다.


메서드의 경우 this의 객체 타입이 타입스크립트에 의해서 추론됩니다. 즉, 메서드는 명시적으로 this의 타입을 지정하지 않아도 객체의 구조를 통해 this에 바인딩될 객체 타입이 추론됩니다.

기본적으로 메서드 내부 this에 바인딩되는 객체는 메서드를 호출한 객체가 바인딩됩니다.

위 코드처럼 showInfo 메서드 내부에서 this에 바인딩될 객체가 자동적으로 추론되어 접근 가능한 프로퍼티와 메서드나 프로퍼티에 대해서 자동완서으로 표시해주며 이외 프로퍼티나 메서드에 접근시 에러를 표시해줍니다.

❗️함수는 타입 정제를 무효화

함수 내부에서 외부 상태를 변경하는 경우, 변경된 상태의 타입이 함수 외부에는 영향을 주지 않습니다.

위 코드에서 func 함수의 인수로 obj 객체를 전달했습니다. func 함수 내부에서는 obj 객체의 name 프로퍼티에 숫자 10을 할당하더라도 함수 외부에서는 여전히 string 타입으로 표시됩니다.

즉, 함수 내부에서 타입이 변경되더라도 정확하게 유지되지 않습니다.

매개변수의 반공변성과 이변성

tsconfig.json에서 strictFunctionTypes 옵션이 true이면서, 함수의 매개변수 타입으로 유니온 타입을 사용하는 경우 반공변성이 적용됩니다.

공변성이란 string | numberstring 타입의 경우 string | number 타입에 string 타입을 할당할 수 있습니다.

반공변성이란 string | numberstring 타입의 경우 string 타입에 string | number 타입을 할당할 수 있습니다.

즉, 일반적으로 서브 타입이 상위 타입에 포함되는 것이 아니라 그 반대로 동작하게 됩니다.

위 코드에서 aFunc 함수의 매개변수 타입은 string | number이고, bFunc 함수의 매개변수 타입은 string 입니다.

일반적인 공변성 원칙에 따르면 string | number 타입이 상위 타입이고 string 타입이 서브 타입이어야 하지만 함수의 매개변수에 유니온 타입을 사용하는 경우 그 반대로 동작합니다.

위 그림처럼 aFunc에 bFunc 할당시 에러가 발생하지만, 반대로 bFunc에 aFunc 할당시 에러가 발생하지 않습니다.

bFunc 매개변수 타입이 분명 string이지만 상위 타입은 string | number 유니온 타입에 할당되는 것을 볼 수 있습니다.


tsconfig.json의 strictFunctionTypes 옵션이 false인 경우에는 이변성이 적용됩니다.

이변성은 string | numberstring 타입의 경우 string | number 타입에 string 타입을 할당할 수도 있고, string 타입에 string | number 타입을 할당할 수도 있습니다.

위 그림처럼 매개변수 타입으로 서브 타입 관계를 갖기만 하면 어떤 타입이든 상관하지 않게 됩니다.

profile
Frontend Dev

0개의 댓글