목차
1. Function
2. Generics (제네릭)
3. 다양한 타입의 객체
4. Function overloading VS Generics
1. Function
함수에 대한 데이터 타입을 지정할 때, 함수의 반환값뿐 아니라, 매개변수에도 데이터 타입이 지정되어 있어야 한다.
// 함수 선언식
function add(x: number, y: number): number {
return x + y
}
//함수 표현식
const ad2 = function (x: number, y: number): number {
return x + y
}
//화살표 함수
const add3 = (x: number, y: number): number => x + y
1-1. 매개변수의 여러 타입
한 가지 매개변수에 대해서 매개변수가 있을 수 있고, 없을 수도 있는 상황이 있다. 이때 매개변수를 |(or연산자)를 통해서 2가지 타입을 지정해줄 수 있다.
hello 함수를 호출 할 때, 매개변수가 있거나, 없을 수 있는 함수를 만든다면, 매개변수의 타입을 잘 지정해야 한다.
{
//방법 1
//매개변수를 name: string = '' 이렇게 적어도 된다.
const hello = (name: string | null = null): void => {
if (name) {
console.log(name.length)
console.log(`hello ${name}`)
} else {
console.log("hello ")
}
}
}
{
//방법 2
const hello = (name?: string): void => {
if (name) {
console.log(name.length)
console.log(`hello ${name}`)
} else {
console.log("hello ")
}
}
}
hello()
hello("baekspace")
1-2. 함수 오버로딩 (function overloading)
Ex) 123->321 or 'abc'->'cba'로 만들고 싶다.
const reverseVari = (vari: string | number): string | number => {
if (typeof vari === "string") {
console.log(vari.split("").reverse().join(""))
return vari.split("").reverse().join("")
} else {
console.log(parseInt(vari.toString().split("").reverse().join("")))
return parseInt(vari.toString().split("").reverse().join(""))
}
}
reverseVari("abc")
reverseVari(123)
일반적으로 이런 로직을 통해서 진행을 할 것이다. 하지만 이 코드에는 문제점이 있는데,
리턴값이 2가지 종류이기 때문에 원하는 대로 데이터 타입을 추론할 수 없다. 그래서 매개변수가 string이면 반환값이 string , number이면 반환값이 number로 정확하게 지정해야 한다.
이때 해결할 수 있는 방법이 '함수 오버로딩'이다.
아래는 함수 오버로딩의 대한 예시 코드이다.
//함수 선언식을 이용한 함수 오버로딩
function reverseVari(x: number): number
function reverseVari(x: string): string
function reverseVari(x: number | string): number | string {
const res = x.toString().split("").reverse().join("")
return typeof x === "number" ? parseInt(res) : res
}
const result = reverseVari("123")
// 화살표 함수을 이용한 함수 오버로딩
type ReverseFunction = {
(x: number): number
(x: string): string
}
const reverse = ((x: string | number) => {
const res = x.toString().split("").reverse().join("")
return typeof x === "number" ? parseInt(res) : res
}) as ReverseFunction
const result1 = reverse(123) // return 321 (number)
const result2 = reverse("hello")
2. Generics (제네릭)
확장성이 좋은 코드를 작성하게 된다면 매개변수의 타입에 따라서 반환값의 타입도 똑같이 지정하고 싶은 경우가 있다.
ex)
매개변수 number -> return값 number,
매개변수 string -> return값 string,
매개변수 object -> return값 object,
매개변수 array -> return값 array,
이때 사용할 수 있는 방법이 Generics type이다.
//기본 문법
const echo = <T>(a: T): T => {
console.log(a)
return a
}
echo(1)
echo("a")
echo({ name: "abc" })
echo(["123"])
T는 타입에 대한 매개변수를 뜻한다.
2-1. 함수의 제네릭
interface와 제네릭을 같이 쓸 때, 함수 실행을 하면서 interface로 지정한 타입을 타입의 매개변수에 같이 전달할 수 있다.
interface Props {
name: string
id: string
}
const echo = <T>(a: T): T => {
console.log(a)
return a
}
const props: Props = {
name: "baek",
id: "baekspacee",
}
echo<Props>(props)
echo 함수를 호출할 때 "<Props>"에 의해서 타입의 매개변수 T가 Props 인터페이스로 지정되고, 반환 값의 데이터 타입도 Props 인터페이스로 지정되었다.
2-2. 반환값이 배열인 함수의 제네릭
Array의 경우 매개변수의 타입뿐 아니라 매개변수 안에 있는 요소의 타입도 지정해주어야 한다.
ex) "string []" or "number []"
이 때도 제네릭을 이용하면 쉽게 지정할 수 있다.
const push = <T>(a: T): T[] => {
const result = [a]
console.log(result)
return result
}
push(1)
push("asdf")
3. 다양한 타입의 객체
interface A {
name: string
}
interface B {
age: number
}
interface C {
weight: number
}
const a: A = { name: "baekspace" }
const b: B = { age: 30 }
const c: C = { weight: 75 }
const object = <T>(value: T): T => {
return value
}
console.log(object<A>(a).name)
console.log(object<B>(b).age)
console.log(object<C>(c).weight)
object로 타입은 object안에 배열, 객체가 포함된 상위의 개념이기 때문에 데이터 타입을 제대로 추론하지 못하게 된다.
하지만 제네릭을 이용해서 매개변수로 데이터타입을 지정하게 된다면 호출했을 때 데이터타입을 추론할 수 있어서 해당 인터페이스에 정의된 프로퍼티에 접근이 가능하고 그 데이터 타입의 메서드를 사용할 수 있게 된다.
4. Function overloading VS Generics
유사점 :
1. 서로 다른 데이터 타입을 처리할 수 있는 코드를 작성할 수 있게 한다.
2. 입력과 출력에 대한 타입이 지정되므로 타입을 추론할 수 있게 해 준다.
차이점 :
오버로딩은 이름이 같은 함수의 매개변수의 타입과 반환 값의 데이터 타입을 여러 개 지정할 때 사용할 수 있지만
제네릭은 단일 함수, 데이터를 다양한 타입의 데이터로 조작할 때 사용할 수 코드를 만들 수 있다.
'🟨 JavaScript 🟨 > 🟦TypeScript🟦' 카테고리의 다른 글
브라우저 환경에서의 TypeScript (0) | 2023.04.21 |
---|---|
객체 지향 프로그래밍 (OOP) - 데이터 은닉화 (0) | 2023.04.21 |
TypeScript의 인터페이스, 클래스 및 객체지향프로그래밍 (OOP) (0) | 2023.04.19 |
TypeScript의 Type (0) | 2023.04.19 |
TypeScript 기초, 컴파일 및 컴파일 설정 (0) | 2023.04.18 |
댓글