[구구스터디] 1. Typescript

이효원·2023년 9월 28일
0

구구스터디

목록 보기
2/8
post-thumbnail

리액트를 공부하기에 앞서, 자바스크립트의 확장언어인 타입스크립트 Typescript가 무엇인지 공부해보았다.

☑️ JS vs TS

먼저, 자바스크립트는 Unstrongly Typed Language라서 변수를 선언할 때 자료형을 정해주지 않기 때문에 자료형이 다른 두 변수를 두고 연산을 했을 때 아무 오류도 띄우지 않는다는 문제점이 있다.
예를 들어, 자료형이 'number'인 1과 자료형이 'string'인 "1"을 더하는 연산을 했을 때, 오류가 발생하지 않고 11 이 출력된다.

이러한 문제를 해결하기 위해서 등장한 것이 바로 TypeScript.

타입스크립트는 Strongly Typed Language라서 변수를 선언할 때 자료형을 미리 결정해준다는 차이점이 있다. 이러한 특징으로 인해 위에서 언급했던 문제점을 해결할 수 있다. 즉, 타입스크립트의 경우에는 자료형이 다른 두 변수 사이의 연산 자체에 대해서 오류를 띄워준다.

TS를 사용하면 코드의 양이 많아질 수는 있지만, 실시간으로 디버깅을 할 수 있다는 점이 매우 편리하다.


☑️ TypeScript

TypeScript Playground에서 코드를 입력하면서, 실제 JS로 번역이 어떻게 되는지 확인하면서 읽어보았다.

1. TS 데이터 타입 지정

primitive 타입, 원시 데이터 지정

let student_id:number = 202303007;
let student_name:string = '이효원';
let is_at_school:boolean = true;

any type

let student_id:any = 202303007; //명시적으로 any타입 지정
let student_id; //생략가능

any type을 사용하면 자료형을 지정해줄 수 있다는 타입스크립트의 장점을 누리지 못하기 때문에 사용을 지양.
이와 비슷한 타입으로는 unknown type이 있다.

let value:unknown = 123;

unknown type은 any type과 달리 어떤 타입인지 모르는 것이기 때문에 함부로 연산을 하지 않기 때문에 오류가 발생한다. 그래서 ts만의 장점을 살릴 수 있다.

union type

두 개 이상의 타입을 허용할 때 사용.

let fact: string | number;
fact = 'Hello';
fact = 123;
fact = false; //error

array type

let nums:number[] = [19, 65, 22];
let members:string[] = ['이효원', '이준하', '조훈히'];
let is_cor:boolean[] = [true, false, true];
let someArr:any[] = [0, 1, {}, 'str', [], false]; //any type
let selects:(number | string)[] = [102, 'apple']; //union type

tuple type

자바스크립트에서는 지원하지 않는 데이터타입.
튜플은 크기와 타입이 고정된 배열array라고 이해하면 더 간단하다.

let user:[number, string, boolean];

user = [202303007, '이효원', true];
user = [10, true, '이효원', 20]; //오류(원소 개수, 타입이 맞아야 함)

enum type

열거형 데이터 타입.
타입의 값을 지정하지 않으면 타입 그 전 타입에 +1을 한 값을 자동으로 할당하고,
별도의 값이 지정되지 않으면 타입은 0부터 순서대로 값이 주어진다.

enum Team{
  Manager = 101,
  Planner = 208,
  Developer = 302,
  Designer //302 + 1 = 303 할당
}

let babo:number = Team.Manager; //(enum member) Team.Manager = 101
let mungtang:number = Team.Designer; //(enum member) Team.Designer = 303

function type (return type)

//리턴 값 타입이 명시적으로 설정되지 않는 함수
function assignClass(name:string):void{
  document.documentElement.classList.add(name);
}

//리턴 값 타입이 숫자인 함수
function factorial(n:number):number{
  if(n < 0){return 0;}
  if(n === 1){return 1;}
  return n * factorial(n-1);
}

//리턴 값 타입이 문자인 경우
function repeat(text:string, count:number=1):string{
  let result:string = '';
  while(count--){result += text;}
  return result;
}

2. Interface 인터페이스

TS에서의 인터페이스는 두 개의 시스템 사이에 상호 간에 정의한 약속 혹은 규칙을 포괄하여 의미한다.
즉, C++에서 배우는 Class클래스 처럼 타입의 '틀'로써 사용할 수 있는 것이 인터페이스이다.
(자바에서의 인터페이스와는 조금 다른 개념.)

//인터페이스 생성
interface Human {
  name: string;
  age: number;
  talk(): void;
}

//인터페이스 자체를 타입으로 사용하여 객체 생성
const person: Human = {
  name: "짱구",
  age: 5,
  talk: () => console.log("부리부리"),
};

//매개변수에서 인터페이스를 타입으로 받는다.
function booboo(a:Human):void {
  console.log(`${a.name} is ${a.age} years old`);
};

booboo(person); //짱구 is 5 years old
person.boo(); //부리부리

3. Generics 제네릭

제네릭은 자바에서 공부했던 것과 똑같다.
제네릭이란, 타입을 마치 함수의 파라미터처럼 사용하는 것을 의미한다.

function getText<T>(text: T): T{
  return text;
}

getText<string>('hi');
getText<number>(10);
getText<boolean>(true);

여러가지 타입을 사용하고 싶을 때 any type을 사용할 수 있지만,
any를 사용하면 함수의 인자가 무슨 타입이며, 어떤 값이 반환되는지 알 수 없다.

function logText<T>(text: T[]): T[] {
  console.log(text.length); // 제네릭 타입이 배열이기 때문에 `length`를 허용.
  return text;
}

function logText<T>(text: Array<T>): Array<T> {
  console.log(text.length);
  return text;
}

Generics Interface

function logText<T>(text: T): T {
  return text;
}
// #1
let str: <T>(text: T) => T = logText;
// #2
let str: {<T>(text: T): T} = logText;

위 코드에서 #1과 #2는 같은 의미이다. 두가지 방법 모두 허용.
위 코드를 인터페이스를 사용해서 작성하면 아래와 같다.

interface GenericLogTextFn {
  <T>(text: T): T;
}
function logText<T>(text: T): T {
  return text;
}
let myString: GenericLogTextFn = logText; 

0개의 댓글