dada's

Typescript 사용 이유 & 오버로딩(overloading)과 제네릭(Generic) 본문

Typescript

Typescript 사용 이유 & 오버로딩(overloading)과 제네릭(Generic)

dykang 2023. 11. 10. 20:14
728x90
**이 글은 기본적인 Typescript 문법을 이해하고 복습을 위해 노마드 코더님의 typescript로 블록체인 만들기 강의를 보며 정리한 글입니다! 기본적인 문법 공부 후 읽으시는 걸 추천 드립니다.

 

 

✅타입스크립트 사용이유

1. 타입 안정성

2. 자바스크립트에서의 문제를 해결할 수 있다

 

자바스크립트는 타입 안정성이 없다.

그런데 타입스크립트를 사용하면 자바나 C#과 비슷한 개발 경험을 할 수 있고 JS보다 생상성을 높이고 버그도 줄일 수 있다.

 

[자바스크립트의 문제🚧]

자바스크립트는 유연한 언어 = 개발자를 이해하려함 에러안나게

 

📍EX) 숫자 배열에 boolean타입인 false를 더할경우

[1, 2, 3] + false

‘1,2,3false’

위와 같이 배열이 없어지고 string 형태가 됨 boolean형태인 false는 string이 된다

= 다른 언어들은 위와 같은 경우 에러가 남

 

📍EX) 런타임 에러(콘솔에서 나는에러)

const nico = {name: “nico”} 이와 같은 객체가 있을때

nico.hello() 이렇게 했을 경우 이 함수를 실행한 뒤 에러가 뜸

그런데 보통 다른 언어는 실행하기 전에 객체를 파악하고 hello()라는 함수는 없다고 알려줌 그런데 자바스크립트는 실행되야지만 에러인지 알 수 있음

이상적인 프로그래밍 언어라면 실행되기 전부터 알려줘야됨


오버로딩(Overloading)

함수 타입의 signature를 만들때 call signature가 여러 개 일 경우

 

📍EX)

type Config = {
	path: string,
	state: object
}

//오버로딩
type Push = { 
	(path: sting): void
	(config: Config): void
}

const push: Push = (config) => {
	if(typeOf config === "string") {console.log(config) }
	else { console.log(config.path) }
}

 

제네릭(Generic)

 

💡다형성(Polymorphismm) : 다양한 형태나 구조 혹은 모양이라는 뜻

 

📍EX) 배열을 하나씩 꺼내주는 함수를 만들 때, 제네릭타입을 안쓸 경우

type SuperPrint = {
	// 파라미터로 number로 된 배열을 받고 값은 return하지않는 void함수의 call signature
	(arr: number[]):void
	(arr: boolean[]):void
	(arr: string[]):void
}

// 배열의 값을 하나씩 꺼내주는 함수
const superPrint: SuperPrint = (arr) => {
	arr.forEach(i => console.log(i))
}

superPrint([1,2,3])
superPrint([true, false, true])
superPrint(["a", "b", "c"])
// => 이런식으로 타입이 늘어날때마다 각 타입을 추가해줘야 함

 

위와 같은 예제처럼 타입이 여러개인 경우 타입을 계속 추가해주는 것 보단 다형성을 활용할 수 있다. ⇒ generic활용

제네릭(generic)이란 placeholder같은 것 ⇒ 타입을 추론해서 함수를 사용

제네릭을 사용하는 경우 ⇒ call signature안에 어떤 타입이 들어올지 모를때

 

📍 EX) 위 코드를 제네릭으로 만들 경우

type SuperPrint = {
	// 시그니쳐 앞에 꺽쇠<>로 제네릭이 올 걸 알려줌 
	// 제네릭으로 받을 값의 타입을 꺽쇠안에 써놨던 타입을 넣어주면됨
	// T나 V를 많이 쓰지만 뭐라고 쓰든 상관은 없음 신경ㄴ 패키지나 라이브러리도 볼 수 있음
	<TypePlaceholder>(arr: TypePlaceholder[]):void
}

// 배열의 값을 하나씩 꺼내주는 함수
const superPrint: SuperPrint = (arr) => {
	arr.forEach(i => console.log(i))
}

// 전부 가능
superPrint([1,2,3])
superPrint([true, false, true])
superPrint(["a", "b", "c"])
superPrint([1, "b", false, 4])

// 만약 any를 사용한다면..
type SuperPrint = {
	(arr: any[]):any
}

const superPrint: SuperPrint = (arr) => arr[0]

const a = superPrint([1, "b", false, 4])
a.toUpperCase() 
// a는 1인데 number이기 때문에 실행하면 에러가 날것임. 
// 그런데 제네릭쓰면 실행하기 전에 에러남(빨간줄)

 

any랑 비슷한거 같은데 any를 사용하지 않는 이유 = 제네릭은 타입을 추론해줘서 어떤 타입인지(number, string..)을 알 수 있고 any는 any자체가 타입임 어떤 타입인지 알 수 없음

 

📍 EX) 제네릭을 하나 더 추가하고 싶을 경우

type SuperPrint = <T, M>(a:T[], b:M) => T

const superPrint: SuperPrint = (a) => a[0]

const a = superPrint([1, "b", false, 4], "m") // 이렇게하면 두번째 파라미터가 제네릭M인줄 앎

 

📍 EX) 함수에서 제네릭 사용하는 경우

function superPrint<T>(a: T[]){
	return a[0]
}

const a = superPrint([1, "b", false, 4])

 

728x90

'Typescript' 카테고리의 다른 글

Typescript에서의 Class, 추상클래스  (2) 2024.01.24
Comments