😎 타입스크립트에서 함수 정의
자바스크립트에서 함수를 정의 할 때 매개변수와 어떤 값을 반환 할지 써준다. 타입스크립트도 마찬가지다.
여기에 추가로 타입만 작성해주면 끝이다.
// 일반 함수
function func(a: number, b: number): number {
return a + b;
}
// 화살표 함수
const add = (a: number, b: number): number => a + b;
● 매개변수의 기본값이 이미 정의된 경우
function introduce(name = "진형", tall?: number) {
console.log(`name : ${name}`);
if (typeof tall === "number") {
console.log(`tall : ${tall + 10}`);
}
}
기본값을 매개변수에 넣고 따로 타입을 설정 안해줘도 된다.
만약 선택적 프로퍼티인 매개변수가 있다면 반드시 필수 매개변수 뒤에 써줘야 한다.
또한 여기서 선택적 프로퍼티의 타입은 number | undefined 여서 반드시 타입 좁히기를 통해 사용하자.
● 나머지 매개변수
만약 여러개의 숫자를 인수를 받는 함수가 있다고 가정하자. 그럴 경우 나머지 매개변수 rest로 배열 형태로 number 타입을 선언하자.
function getSum(...rest: number[]) {
let sum = 0;
rest.forEach((item) => (sum += item));
return sum;
}
✏️ 함수 타입 선언식
함수 타입을 타입 별칭과 함께 별도로 정의할 수 있다.
이러면 함수의 선언 및 구현 코드와 타입 선언을 분리할 수 있어 유용하다.
type Operation = (a: number, b: number) => number;
const add: Operation = (a, b) => a + b;
const sub: Operation = (a, b) => a - b;
const multiply: Operation = (a, b) => a * b;
const divide: Operation = (a, b) => a / b;
이렇게 하면 여러개의 함수가 동일한 타입을 갖는 경우에 코드의 간결성이 좋아진다.
📞 함수 호출 시그니쳐
type Operation2 = {
(a: number, b: number): number;
name: string;
};
const add2: Operation2 = (a, b) => a + b;
add2(1, 2);
add.name;
자바스크립트에서 함수도 객체이기 때문에, 함수를 객체 정의하듯 함수의 타입을 별도로 정의할 수 있다.
또한 프로퍼티를 추가로 정의할 수 있어, 함수이자 일반 객체를 의미하는 타입으로 정의된다. 이를 하이브리드 타입이라 부른다.
🪃 함수 오버로딩
함수 오버로딩이란 하나의 함수를 매개변수의 개수나 타입에 따라 다르게 동작하도록 만드는 문법이다.
타입스크립트에서 함수 오버로딩을 하려면 우선 오버로드 시그니쳐를 만들어 줘야 한다.
// 버전들 -> 오버로드 시그니쳐
function func(a: number): void;
function func(a: number, b: number, c: number): void;
// 실제 구현부 -> 구현 시그니쳐
function func(a: number, b?: number, c?: number) {
if (typeof b === "number" && typeof c === "number") {
console.log(a + b + c);
} else {
console.log(a * 20);
}
}
func(1); // ✅ 버전 1 - 오버로드 시그니쳐
func(1, 2); // ❌
func(1, 2, 3); // ✅ 버전 3 - 오버로드 시그니쳐
오버로드 시그니쳐를 선언해줬으면 구현 시그니쳐를 선언해줘야 한다. 따로따로 써줘도 되지만 두개다 같이 써줄 수 있다는 것을 표현하기 위해 여기선 같이 써줬다.
원하는 함수를 사용하기 위해서 타입 좁히기를 통해 사용할 수 있다.
⚔️ 사용자 정의 타입 가드
사용자 정의 타입가드란 참 또는 거짓을 반환하는 함수를 이용해 우리 입맛대로 타입 가드를 만들 수 있도록 도와주는 타입스크립트의 문법이다.
type Dog = {
name: string;
isBark: boolean;
};
type Cat = {
name: string;
isScratch: boolean;
};
type Animal = Dog | Cat;
function warning(animal: Animal) {
if ("isBark" in animal) {
console.log(animal.isBark ? "짖습니다" : "안짖어요");
} else if ("isScratch" in animal) {
console.log(animal.isScratch ? "할큅니다" : "안할퀴어요");
}
}
Dog와 Cat을 정의하고 두 타입의 유니온 타입인 Animal 타입을 정의했다. 매개변수로 Animal 타입의 값을 받아 동물에 따라 각각 다른 울음 소리를 콘솔로 나타내려 하고 있다.
하지만 in 연산자를 통해 타입을 좁히면 타입의 프로퍼티 값이 변하거나 삭제될 경우 원하는 타입이 안나올 수 있다.
※ 실제로 Dog의 프로퍼티 isBark를 isBarked로 바꾸면 오류는 안나지만 unknown타입으로 설정되는 모습을 확인했다.
🤔그러면 어떻게 해야 할까?
// Dog 타입인지 확인하는 타입 가드
function isDog(animal: Animal): animal is Dog {
return (animal as Dog).isBark !== undefined;
}
// Cat 타입인지 확인하는 타입가드
function isCat(animal: Animal): animal is Cat {
return (animal as Cat).isScratch !== undefined;
}
function warning(animal: Animal) {
if (isDog(animal)) {
console.log(animal.isBark ? "짖습니다" : "안짖어요");
} else {
console.log(animal.isScratch ? "할큅니다" : "안할퀴어요");
}
}
animal is Dog를 정의하면 이 함수가true 또는 false를 반환한다. 이때 반환값이 true면 이 값이 Dog타입임을 보장한다는 의미다. 따라서 in 연산자를 사용했을 때보다 정확히 타입 가드를 할 수 있다.
실제 isBark의 프로퍼티를 isBarked로 바꾸니 오류가 났다.
'TypeScript' 카테고리의 다른 글
[TypeScript] - 변수 타입 선언 (1) | 2023.10.29 |
---|---|
[TypeScript] - 기본다지기2(Complier Option) (0) | 2023.10.28 |
[Typescript] - 기본 다지기(실행 및 설치 방법) (0) | 2023.10.27 |