// (매개변수/ 콜론/ 타입)
function greet (person: string) {
return `Hi there, ${person}!`
}
greet("soyeon");
// `Hi there, soyeon!`
// Argument of type 'number' is not assignable to parameter of type 'string'.
greet(3)
매개변수의 기본 값을 사용하려면 다음과 같이 사용하면 됩니다.
// (매개변수/ 콜론/ 타입/ 기본값)
function greet (person: string = 'stranger') {
return `Hi there, ${person}!`
}
greet();
// `Hi there, stranger!`
함수를 호출할 때 매개 변수만큼 인수를 전달해야하며 각 인수는 타입에 맞아야 합니다.
const doSomething = (person: string, age: number, isFunny: boolean) => {};
doSomething("soyeon", 32, true);
// Expected 3 arguments, but got 1
doSomething("soyeon");
//doSomething(person: string, age: number, isFunny: boolean): void
doSomething("ChickenFace", 78, 'think so');
소괄호(()) 다음에 return 할 타입 값을 지정합니다.
// (매개변수 Type Annotation): return Type Annotation
function square (num: number): number {
return num * num;
};
// Type Inference
// 타입 애너테이션을 지정하지 않고 타입 추론을 통해 return에 어떤 타입 값이 할당되었는지 파악
// function square(num: number): number
function square(num: number) {
return num * num;
}
square(3);
return이 없다면 void 타입으로 적용됩니다.
void는 아무것도 반환하지 않는 함수의 반환 타입으로 사용합니다.
따라서 반환 값은 undefined를 갖습니다.
// function square(num: number): void
function square(num: number) {
num * num;
}
// 사용 불가
// Type 'number' is not assignable to type 'void'
function square(num: number): void {
return num * num;
}
Never도 Void와 같이 아무것도 반환하지 않는 함수의 반환 타입으로 사용합니다.
차이점이라면 Void는 아무것도 반환하지 않은 경우 함수의 백그라운드에서 undefined 상태로 반환됩니다.
하지만 Never은 함수가 아무것도 반환하면 안 된다는 것을 나타내기 위해 쓰이고, 일반적으로 예외를 발생시키는 함수에 사용됩니다.
// void와 역할은 같지만 '절대 반환되면 안된다'는 의미를 전달 할 수 있는 경우
// 반환없이 에러만 발생하는 함수
function makeError(msg: string): never {
throw new Error(msg);
}
// 반환없이 영원히 반복만 하는 함수
function gameLoop(): never {
while (true) {
console.log("GAME LOOP RUNNING");
}
}
return 값의 타입이 조건문에 따라 달라질 경우 |을 사용합니다.
// function rando(num: number): string | number
function rando(num: number) {
if(Math.random() < 0.5) {
return num.toString();
}
return num;
}
화살표 함수의 Type Annotation은 아래와 같이 생겼습니다.
const add = (x: number, y: number): number => {
return x + y;
}
타입스크립트는 Type Inference를 하여 매개변수 color가 string 타입이라는 것을 알 수 있습니다.
const colors = ["red", "orange", "yellow"];
colors.map((color) => {
return color.toUpperCase();
});

call signatures는 함수의 인자와 반환 타입이 무엇인지 알려주는 것 입니다.
type alias로 call signatures를 만들 수 있습니다.
// call signatures
type Add = (a:number, b:number) => number;
const add: Add = (a, b) => a + b
콜백 함수에도 적용할 수 있습니다.
// call signatures
type DescribableFunction = {
// 속성 타입 지정
description: string;
// 인수 타입과 반환 타입 지정
(someArg: number): boolean;
};
// 콜백 함수에 미리 작성한 call signatures를 적용
function doSomething(fn: DescribableFunction) {
console.log(fn.description + " returned " + fn(6));
}
function myFunc(someArg: number) {
return someArg > 3;
}
// myFunc의 속성 추가
myFunc.description = "default description";
doSomething(myFunc);
// 6이 3보다 크기 때문에 true
call signatures를 사용하면 함수 구현과 타입 지정을 분리하여 작성할 수 있는 이점이 생깁니다.
오버로딩은 함수가 여러개의 call signatures를 가지고 있을 대 발생시킵니다.
// 여러개의 call signatures
type Add = {
(a: number, b: number) : number
(a: number, b: string) : number
}
// 인수 b가 number일 수도 string일 수도 있는 경우가 있음
const add: Add = (a, b) => {
if(typeof b === "string") return a
return a + b
}
인수의 개수에 따라 변하는 call signatures를 여러개 가지고 있을 수 있습니다.
// 여러개의 call signatures
type Add = {
(a: number, b: number) : number
(a: number, b: number, c: number) : number
}
// 인수 b가 number일 수도 string일 수도 있는 경우가 있음
const add: Add = (a, b, c?:number) => {
if(c) return a + b + c
return a + b
}
타입 스크립트에서 함수는 모두 다른 형태의 타입을 가질 수 있습니다.
매개변수의 숫자, 타입, 반환 타입 등에 따라 다양한 형태를 갖는 것을 Polymorphism이라고 합니다.
배열의 값을 출력하는 함수를 사용하려고 합니다.
배열의 값의 타입은 어떤 것도 될 수 있을 때 아래와 같이 모든 가능성을 조합해서 call signatures를 구현해야 합니다.
type SuperPrint = {
(arr: number[]):void
(arr: boolean[]):void
(arr: string[]):void
(arr: (number|boolean)[])
...
}
const superPrint: SuperPrint = (arr) => {
arr.forEach(i => console.log(i))
}
sperPrint([1, 2, 3, 4])
sperPrint([true, false, true, false])
sperPrint(["1", "2", "3", "4"])
superPrint([1, true, 3, false])
...
모든 가능성을 조합해서 call signatures를 구현해야 하는 일은 비효율적이고 이럴 때 제네릭을 사용합니다.
제네릭을 사용하면 다음과 같이 코드를 변경할 수 있습니다.
type SuperPrint = {
<TypePlaceholder>(arr: TypePlaceholder[]):void
}
const superPrint: SuperPrint = (arr) => {
arr.forEach(i => console.log(i))
}
sperPrint([1, 2, 3, 4])
sperPrint([true, false, true, false])
sperPrint(["1", "2", "3", "4"])
superPrint([1, true, 3, false])
...
더 자세한 내용은 제네릭 게시글을 참고해 보시면 도움이 됩니다.