[TypeScript] TypeScript를 사용해봅시다

하영·2022년 9월 25일
0

TypeScript

목록 보기
1/2
post-thumbnail

22.07.08 노션에 작성한 문서를 옮긴 것입니다. (원본 삭제됨)

0. 들어가며

프론트엔드에서 주로 사용하는 언어는 자바스크립트 입니다. 저도 여러 사이드 프로젝트를 진행 하면서 수도 없이 사용해왔구요! 자바스크립트는 타입을 지정하지 않아도 되고 묵시적으로 타입이 지정되어 자동 형변환이 정말 편했습니다. 하지만 이 부정확한 타입 지정이 백엔드와의 소통에서 문제를 일으키는 경우가 잦았습니다.(특히 런타임 에러가 너무 잦았음 ㅠㅠ !) 백엔드와 규칙을 정하면 좋으련만... 이라고 생각하던 중에!

규칙의 수단으로 타입스크립트를 채택하기로 했습니다. 규모가 큰 프로젝트나 기업에서 타입스크립트를 선호하는 이유를 알 것만 같았습니다.. 그러한 단순한 이유에서 타입스크립트 학습을 시작했습니다!

이 글에서는, 타입스크립트가 어떤 것인지? 왜 사용하는지? 에 대해 알아 본 것을 간단히 정리하고, 기본 문법을 축약하여 정리해보았습니다!

1. TypeScript란?

위에 언급한 불편사항을 해결하고자 타입스크립트를 도입하는 사례가 점차 늘고 있습니다. 자바스크립트는 되도록이면 지양하는 방향으로 흐르고 있죠!

타입스크립트는, MicroSoft에서 개발하고 관리하는 오픈소스 프로그래밍 언어 입니다. 그 어떠한 OS, 호스트, 브라우저에서 모두 작동합니다.

타입스크립트는 자바스크립트에 정적 타입을 지정할 수 있는 언어입니다. 자바스크립트의 상위 집합 언어라고 볼 수 있어요! 타입스크립트는 실행 시 자바스크립트로 컴파일되어 실행되고, 정적 타입 언어이기 때문에 실행 속도는 자바스크립트보다 약간 저하됩니다. 하지만 코드 안정성이 높기 때문에 타입스크립트를 선호하고 있습니다.

TypeScript는 정적 타입을 지원함으로써 컴파일 단계에서 타입으로 인한 오류를 잡아낼 수 있습니다. C/C++ 및 JAVA와 같이 타입을 명시적으로 지정해준다면 변수의 성격을 보다 쉽게 예측할 수 있고 개발자의 의도를 명확하게 코드로 확인할 수 있습니다.

2. TypeScript를 도입한 이유는? (with JavaScript)

적어도 프론트엔드에서의 런타임 오류를 줄이고, 백엔드와 통신할 때 타입 불일치로 인한 오류를 줄이기 위해 타입스크립트를 도입하기로 결정했지만, 가장 큰 이유는 개발자들의 경험을 위해서 였습니다.

타입스크립트를 선호하는 기업이 늘고있고 ,이것은 곧 프론트엔드 개발자가 필수로 배워야 하는 것이 늘었다 라고 생각했기 때문입니다.( 타입스크립트 개발자를 우대하는걸 아는데, 안배울 순 없으니까! )

그리고, 기술적인 부분에 있어서 아래와 같은 이유로 도입하였습니다.

  • props의 타입 확인이 쉬우며, 변수와 맞지 않는 값을 삽입하여 생기는 오류를 사전에 방지할 수 있다.
    • string 값을 저장하기로 한 state 변수에 배열을 대입한 후 해당 변수에 string변수 내장함수를 사용하려고 할 때 생기는 오류 ... 와같은 것 방지
  • 타입을 지정하기 애매할 때는 타입 추론을 이용한 타입 제어가 가능하다
  • 테스트 단계에서 발견하지 못한 에러를 발견할 수 있다.
    • 주로 맞지 않는 데이터 삽입으로 인한 에러..
    • 오타로 인한 에러를 실행할 때 되어서야 발견하는 참사를 대비

3. TypeScript 기본 문법

도입을 하려면 기본 문법은 익히고 시작해야죠! (07.08 기준)

가장 기본적인 문법과 react에 사용할 수 있을 정도로만 문서로 작성하였고, 추가로 학습이 필요한 부분은 글을 나눠 포스팅 할 예정입니다.

문법 공부 및 해당 글 작성은 타입스크립트 핸드북의 도움을 받았습니다.

3.1 기본 타입

기존 자바스크립트에서 변수를 선언할 때는 let 이나 const를 이용해 선언하였고, 함수도 const로 선언하였습니다. 따로 변수의 타입이나 함수의 반환 타입을 지정해주지 않았었는데요, 타입스크립트 에서는 변수나 함수의 정적 타입을 지정하여 특정 타입의 값만 저장할 수 있도록 합니다.

이 때 사용하는 정적 타입의 종류는 아래와 같습니다

  • Boolean - true/false 진위 여부를 저장하는 타입
let true_value: boolean = true;
true_value = "true"; // error
let false_value: boolean = false;
false_value = "false" // error
  • Number - 숫자로 된 값을 저장하는 타입
let count = 0 ; // 타입추론을 통해 count는 number.
let count2: number = 1;                             
  • String - 문자열로 된 값을 저장하는 타입
let str = "Hello World!"; // 타입추론을 통해 str은 string.
str = 0 ; // 정의한 타입과 다른 타입 대입시 error
let str2: string = "my name is hayoung!"; 
  • Array - 자바스크립트와 동일한 배열
let number_arr : number[] = [1,2,3,4,5]; // 숫자 배열
let string_arr : string[] = ["apple","grape","orange"]; // 문자열 배열
let boolean_arr : boolean[] = [true,false,true,false,false]; // boolean 배열

number_arr.push("문자열 삽입?"); // 정의한 타입과 다른 타입 삽입시 error 
string_arr.push(0); // 정의한 타입과 다른 타입 삽입시 error
  • Tuple - 길이가 고정되고 각 요소의 타입이 지정되어 있는 배열
let tuple_arr: [string,number,string]=["I am", 24, "years old"];
tuple_arr[1] = "30"; // 정의하지 않은 타입, 인덱스로 접근시 error 
  • Enum - 자주 사용하는 상수의 열거형 집합 또는 변수
enum Fruits { // 대문자로 시작
	apple = "사과",
	banana = "바나나",
	orange = "오렌지",
	watermelon = "수박",
}; // enum 선언

let fruit: Fruits = Fruits.apple;
console.log(fruit); // 사과

let fruit2: Fruits = Fruits[1]; // 인덱스 접근 가능
console.log(fruits2); // 바나나

하지만 열거형 사용을 지양하라는 의견도 있더라고요?
https://engineering.linecorp.com/ko/blog/typescript-enum-tree-shaking/

  • Any - 해당 변수에 대해 모든 타입을 허용 한다는 의미
let any_value : any = 4; // 가능
any_value = "hello world"; // 가능
any_value = true; // 가능

3.2 타입 추론과 타입 단언

  • 타입 추론
    • 처음 변수가 선언된 후 대입된 값으로 해당 변수의 타입을 추론하여 타입을 지정하는 방식
  • 타입 단언
    • 개발자가 컴파일러에게 특정 변수에 대해 타입 힌트를 주는 것입니다. 개발자가 확신을 가지고 특정 변수에 해당 타입을 고정함으로써, 디버깅이 완료되었다고 해석하고 컴파일러는 타입 에러 없이 컴파일 시킵니다.
    • JSX, TSX 문법을 사용할 땐 as 단언만 허용합니다.
let value : any = "hello world!" ; // any 타입으로 선언
let value_length : number = (<string>value).length; 
value_length : number = (value as string).length;
// value가 string임을 확신하고 length() 내장 함수 호출

3.3 함수 반환 타입 지정

  • 함수의 타입은 반환할 데이터의 타입과 동일하게 지정하면 됩니다.
const add = (num1: number, num2: number):number => {
	return num1+num2; // num1+num2 의 값은 number타입
} // 화살표 함수

function subtract(num1: number, num2: number):number{
	return num1-num2;
} // 기명 함수

3.4 함수 매개변수의 타입 지정

  • 함수 매개변수에도 타입 지정은 필수로 이루어져야 합니다.
  • 기본 매개변수 모든 것이 올 수 있으며, 객체 및 사용자 선언 타입 모두 올 수 있습니다.
const hello = (name:string, age:number):string=>{
	return `hello! my name is ${name}, ${age} years old";
}
  • 선택적으로 매개변수를 받을 수 있습니다.
    • 자바스크립트 에서는 함수에서 선언한 매개변수를 모두 사용할 필요는 없으며, 함수 호출시 인수를 주지 않는다면 해당 파라미터는 undefined 가 됩니다.
    • 타입스크립트 에서는 모든 매개변수가 함수에 필요하다고 판단하여, 함수 호출 시 매개변수 하나라도 빠지게 된다면 컴파일 시 에러를 뿜어냅니다.
    • 타입스크립트 에서도 매개변수를 선택하여 사용할 수 있습니다. 이를 위해서는 매개변수 이름 끝에 ? 를 붙이면 됩니다.
const starbucks_coffee = (coffee1:string, coffee2?:string, coffee3?:string):string =>{
	let receipt = coffee1;
	if (coffee2) receipt += coffee2;
	if (coffee3) receipt += coffee3;
	return receipt;
}
console.log(starbucks_coffee("디카페인 아메리카노"); // "디카페인 아메리카노"
console.log(starbucks_coffee("카페라떼","아메리카노","자몽허니블랙티","돌체라떼"); // 너무 많은 매개변수 error
console.log(starbucks_coffee("아메리카노","돌체라떼","자몽허니블랙티"); // 매개변수 개수가 정확히 일치함.
  • 기본 초기화 매개 변수: 매개변수의 기본값을 기존 자바스크립트와 동일하게 지정할 수 있습니다.
    • 개발자가 매개변수 값을 주지 않았거나 undefined를 주었을 때 대신 할당할 값을 지정할 수 있습니다.
    • 기본 초기화 매개변수의 타입에 대해서는 타입추론으로 진행됩니다.
const printName = (first_name:string,last_name="길동"):string => {
	return first_name+last_name;
}
console.log(printName("전"); // 전길동 출력
console.log(printName("전","하영"); // 전하영 출력
console.log(printName()); // 필수 인수를 채우지 않아 error
  • 매개변수를 받아올 때 비구조화 할당이 가능합니다.
// 기본 자바스크립트 에서의 비구조화 할당
const post = {
	title:"게시글 제목",
	content:"게시글 본문",
};
const {title,content}=post;
// 타입스크립트 에서의 비구조화 할당
interface Post{
	title:string,
	content:string,
}; // 객체의 타입을 지정하는 interface. 뒤에서 공부
const post_obj:Post = {
	title:"게시글 제목",
	content:"게시글 본문",
}
// 쉬운 방법
const {title,content}:{title:string,content:string} = post_obj;

// 권장 방법
const {title,content}:Post = post_obj; 
// 자주 사용되는 타입은 공용타입선언 가능.
// 타입스크립트 함수에서 객체 매개변수의 타입 지정
interface Post{
	title:string,
	content:string,
}

const postPrint = (post_obj:Post):string=>{
	return post_obj.title + post_obj.content;
}

// 비구조화 할당 적용 타입 지정
const postPrint = ({title,content}:Post):string=>{
	return title+content;
} // 가독성은 이게 더 좋죵?
  • 나머지 매개변수 활용 가능
    • https://velog.io/@kite1993/타입스크립트에서-Rest-문법과-디스트럭쳐링-할당-사용하기
    • 한번씩 다수의 매개변수를 한번에 묶어서 표현할 일이 있습니다
    • 그리고 매개변수가 몇 개가 될지 모르는 경우가 있습니다
    • spread 연산자 - ES6에서 추가된 문법으로, 배열, 객체, 함수 등을 다루기 쉽게 만들었습니다.
      • 자바스크립트, 타입스크립트는 기본적으로 참조연산이기에, 특정 값을 변수에 대입하면 복사 가 이루어지는 것이 아닙니다. 그렇기에 쉽게 복사를 하려면 spread 연산자를 사용하게 됩니다.
      • spread 연산자는 로 사용한다. 값을 전개한다는 의미로, 자세한 내용은 링크 참조 https://paperblock.tistory.com/62
    • spread 연산자를 이용하여 매개변수를 모을 수 있습니다.
const make_arr = (...rest:number[]):number[]{
	return rest;
}
console.log(make_arr(1,2,3,4,5)); // [1,2,3,4,5]

3.5 유니온 타입과 리터럴 타입

  • 유니온 타입
    • 변수의 값이 여러 타입을 가질 수 있을 때 주로 사용합니다.
    • 타입과 타입을 | 연산자로 연결하여 사용합니다.
let age:number | string;
age = 24; // 대입 가능
age = "24" // 대입 가능
  • 리터럴타입
    • 숫자 또는 문자열을 지정할 수 있습니다.
    • 문자열과 숫자형 리터럴 타입 지정이 가능합니다.
type Color = "red" | "green" | "blue";
let color:Color = "yellow"; // 에러 발생!

3.6 interface를 사용한 사용자 타입 선언

  • 클래스 또는 객체의 타입을 지정할 때 사용하는 문법
  • 객체의 타입을 지정할 때 사용합니다. 속성으로 변수, 함수 모두 가능합니다.
  • JAVA의 interface와 별 다를 것이 없어 보인다…
  • 타입을 여러개 지정하는 용도로 가장 많이 사용하지만, 기본뼈대를 만들어 어디든 사용할 수 있기에 상세 내용은 핸드북을 참고하면 좋습니다.
interface Person {
	name:string,
	age:number,
	phone:number,
	address?:string, // 속성으로 있어도 되고 없어도 되고
}
let person1:Person = {name:"전하영",age:24,phone:01054274189}; // address 없음
let person2:Person = {
	name:"홍길동",
	age:20,
	phone:01012345678,
	address:"사랑시 고백구 행복동", 
};

3.7 제네릭

다양한 타입을 지원하여, 재사용 컴포넌트 생산성을 높여주는 역할을 합니다. 타입을 일반화 한다는 의미를 가졌으며, 데이터의 타입을 호출시에 지정할 수 있도록 합니다. any와는 다른 개념입니당!
https://developer-talk.tistory.com/195

  • 제네릭 사용하기
function return_value<T>(arg:T):T{
	return arg;
} // 기본 함수 사용
const print_function = <T>(arg:T):T => {
	return arg;
} // 화살표 함수. .ts 문서에서는 이렇게 사용

const print_functin = <T extends {}>(arg:T):T =>{
	return arg;
} // 화살표 함수. .tsx 문서에서는 이렇게 사용
  • T라고 하는 타입 변수를 추가하였습니다. T가 어떤 타입이 될지 지정하는 부분은 함수를 호출할 때 지정하면 됩니다.

4. 마치며

타입스크립트를 충분히 공부하여 실전에서 사용한다면, 다른 언어와 다를 것 없이 클린코드 작성 능력이 올라갈 것으로 기대합니다. 저도 열심히 해보고, 타입스크립트의 기능을 최대한 활용해보는 노력을 할 것입니다!

기존에 간단히 진행했던 프로젝트에서 타입스크립트를 적용 했었지만, 문서 하나 제대로 읽어보지 않은 채

아이 뭐 ... 타입만 지정하면 되는거겠지 ~ 🤔

라고 생각했는데 이는 정말 잘못된 자세였습니다. 진짜 타입만 지정하고 다른 기능을 사용하지 못했었습니다. 문서를 단 한번 정독하였는데도 앞으로 타입스크립트 사용의 방향성을 잡게 되었습니다.

다들 타입스크립트를 공부하여 자신이 짠 코드의 안정성을 높여봅시다! 화이팅 ㅎㅎ

공부하며 작성한 글이기 때문에 부족한 부분이나 궁금한 점이 있으시다면 댓글 자유롭게 남겨주세요 😊 감사합니다!

profile
maker를 넘어 solver를 지향합니다.

0개의 댓글