함수에서는 어떻게 작성하고 쓸까? 거두절미하고 바로 보자.
function hello (name: string) {
return `Hello ${name || "world"}`
}
const result = hello() // error가 뜬다.
위 예시를 보면 name이라는 매개변수를 갖는 hello함수를 만들었고, name이 없을 때 대신 나타내줄 값도 ||
를 통해 표시했다.
그런데 매개변수값 없이 helle()
만 부르면 에러가 뜬다.
TS는 보다 정확히 알려줘야한다는 것. 때문에 name값 앞에 옵션으로 만들어줄 ?
를 붙여야 한다.
function hello(name?: string) {...}
참고: default 정하기
위처럼 옵션처리가 아니어도 JS에서 쓰듯이 default처리를 해주면 된다.
function hello (name="world") { return `Hello ${name}` }
function hello (name: string, age?: number):string {
if (age !== undefined) {
return `Hello, ${name}. You are ${age}.`
} else {
return `Hello, ${name}.`
}
}
const sam = hello("Sam");
const samAge = hello("Sam", 33);
console.log(sam);
console.log(samAge);
위 함수는 name은 string으로 받는 필수적인 매개변수이고, age는 number type을 가지는 매개변수로써 선택적으로 받는다. 그리고 string을 리턴한다.
그런데 위에서 옵션인 age를 앞에서 작성하면? 어떻게 될까?
function hello (age?: number, name: string):string {
// ...
}
빨간 밑줄이 그어진다. 즉 필수 매개변수가 앞에 작성되어야 하는 것이다.
만약 위처럼 옵션인 age를 앞에 굳이 쓰고 싶다면 다음과 같이 직접 명시적으로 지정해서 바꿔줘야한다.
function hello (age: number | undefined, name: string):string {
if (age !== undefined) {
return `Hello, ${name}. You are ${age}.`
} else {
return `Hello, ${name}.`
}
}
const sam = hello(undefined, "Sam");
const samAge = hello(33, "Sam");
console.log(sam);
console.log(samAge);
function add (...nums) {
return nums.reduce((result, num) => result + num, 0);
}
add(1,2,3); // 6
add(1,2,3,4,5,6,7,8,9,10) // 55
위 함수는 나머지 매개변수를 활용해주고 있다. 나머지 매개변수는 여러 개로 들어오는 매개변수를 배열
로 처리 가능하게 해준다.
나머지 매개변수 정리글 ← 링크 클릭시 이동
무엇으로? 배열로! 그렇기 때문에 다음처럼 배열로 type을 설정해준다.
function add (...nums: number[]) {
// ...
}
interface User {
name: string;
}
const Sam: User = {name:'Sam'}
function showName() {
console.log(this.name)
}
const a = showName.bind(Sam);
a();
위 코드를 보면 a
를 선언하고 할당할 때 bind
를 이용해 this
를 Sam객체로 강제하고 있다. 그렇기 때문에 log에는 "Sam"이 찍힐 것이다.
bind
에 대한 것인 요기 링크로 이동 !
그런데 showName함수에서 this에 빨갛게 밑줄이 간다. 그 이유는 this에 타입이 결정되지 않았기 때문이다.
그럼 어떻게 설정해줘야할까?
function showName(this:User) {
console.log(this.name)
}
위처럼 함수의 매개변수 첫번째 자리에 this의 타입을 설정해주면 된다.
만약 매개변수가 있다면? 그저 똑같이 제일 앞에 써주면 된다.
function showName(this:User, age:number, gender:'m'|'f') {
console.log(this.name, age, gender)
}
const a = showName.bind(Sam);
a(33, 'm');
주의할 점은 보이는 매개변수가 세개라고 해서 세개의 값을 필요로 하는 것이 아니라는 것이다. 위에서 this는 넣어줄 값이 아니기 때문이다.
interface User {
name: string,
age: number
}
function join (name: string, age: number|string): User | string {
if (typeof age === "number") {
return {
name,
age,
};
} else {
return "나이는 숫자로 입력해주세요.";
}
}
위 예시 코드를 보면 에러표시가 뜨지 않아 문제가 없어보인다. 그렇다면 이를 실행해보면 어떨까?
const sam: User = join("Sam", 30); // error
const jain: string = join("Jane", "33"); // error
위 코드를 써보려 하면 변수명에 빨간 밑줄이 간다. 이유가 무엇일까?
그 이유는 각 변수들에 작성해준 type에 확신이 없기 때문이다.
이게 무슨 말이냐??
위 join
함수를 보면 매개변수 age의 타입이 두 종류가 가능하도록 설정되어 있다.
그리고 함수 안에서 어떤 type의 age가 들어왔냐에 따라 분기를 나눈다.
즉, 함수 자체에서는 이 함수의 return이 User로 될지 string이 될지 정해지지 않았기 때문에 변수 sam
과 jane
입장에서는 나를 User, string으로 미리 지정해 놓기엔 스스로 확신이 안든다! 뭐 요런 의미이다.
설사 뒤에 할당한 join함수의 매개변수의 값이 작성되어 있어도 정적언어이기에 동작된 뒤에 정해질 return의 타입따위 난 모른다! 뭐 이런게 아닐까? 내 스스로 해석해본 약간 뇌피셜식 풀이이다. ㅎㅎ
그렇담 이때는 어떻게 해야하느냐? 이때 쓰는게 overload
이다.
interface User {
name: string,
age: number
}
// overload 작성
function join (name: string, age: number): User;
function join (name: string, age: string): string;
function join (name: string, age: number|string): User | string {
if (typeof age === "number") {
return {
name,
age,
};
} else {
return "나이는 숫자로 입력해주세요.";
}
}
아주 간단하다. 매개변수의 개수나 타입에 따라 다른 방식의 동작 결과를 내는 함수의 경우, 그 경우를 직접 나눠서 같은 함수를 작성해주면 된다.
신기타 신기해~