Typescript 개념 정리 1 - basic & type

thousand_yj·2023년 6월 28일
0

Typescript & React

목록 보기
1/12

Typescript란?

개발 단계에서 Javascript 개발 시 발생할 수 있는 에러를 미리 알려주는 언어. 올바른 IDE와 함께 사용 시 개발자의 실수를 많이 줄여줄 수 있다. 다만 JS 엔진에 내장된 기능이 아니라 브라우저에서 직접 실행할 수 없어 tsc app.ts와 같이 ts파일을 js파일로 컴파일하여 실행해야 한다.
특정 변수가 어떤 자료형이어야 하는지 :를 사용하여 명시해줄 수 있다.

TS 공식 문서

TS vs JS

  • Javascript : 동적Dynamic 타입. 특정 타입에서만 실행되어야 하는 코드가 있는 경우 typeof 연산자를 사용하여 체크해줘야 한다. (런타임 단계에서 에러 잡음)
  • Typescript : 정적Static 타입. 개발 과정에서 변수, 매개변수의 타입을 정의한다. (런타임 중 바뀌지 않음). JS에서 갖고 있는 타입보다 훨씬 많은 타입을 갖고 있어 강력하고 유연한 검사를 수행할 수 있다.

Typescript type

  • number : 정수, 실수를 모두 포함
  • string : 문자열 '', "", `` 모두 포함
  • boolean : 참거짓. js에서 존재하는 truthy, falsy의 개념을 잊지 말것!
  • object : 객체 ex. { age: 30 }
  • array : 여러 개의 타입을 혼용하여 저장할 수 있는 배열 ex. [1,2,3]
  • (new!) tuple : js에는 존재x 자료형. 배열과 동일하게 생겼으나 타입과 길이가 고정됨. ex. [1,2]
  • (new!) enum : js에는 존재x 자료형. 열거되는 자료를 0부터 시작하는 데이터로 변환(특정 값으로 맵핑도 가능)하나, 직접 호출 시에는 눈에 보이는 문자열로 호출이 가능하다. ex. enum Status { ON, OFF}
  • (new!) any : 모든 타입에 다 사용 가능한 無타입. 다만 기본 js를 사용하는 것과 크게 다를 것 없이 동작하므로 실제 ts 코드에서는 사용할 일이 많지 않다.

object

const person = {
  name : "1000yj",
  age : 27,
}

위와 같은 object에서 ts는 object의 타입을 추론한다.

const person = {
  name: string;
  age: number;
}

객체의 값 구분은 ,로 되므로 IDE 상에 표시되는 위의 코드는 ts에 의해 추론된 자료형이다.

tuple

const person : {
  name: string;
  role: [number, string]; // tuple
} = {
  name: "1000yj",
  role: [1, "teacher"],

ts가 타입 추론을 하는 것 대신 명시적으로 해당 타입이 배열이 아니라 튜플임을 알려주는 방식은 위와 같다. role의 특정 인덱스에 잘못된 자료형의 값을 대입하거나, 빈 배열을 대입하는 경우 에러가 발생한다.
다만 주의할 점은 push 메서드는 튜플에서도 작동한다!
특정 n개의 데이터만 필요하고, 그 데이터의 자료형이 고정된 경우 튜플을 사용하면 편리하다

Union type

자료형이 2가지 이상이 가능한 경우, 가능한 자료형을 |에 모두 적어주면 된다. 숫자가 2개 입력되는 경우에는 덧셈 연산을, 그외에 문자열이 섞여 들어오는 경우 문자열 덧셈 연산을 수행하도록 코드를 짜면 다음과 같다.

function combine(input1 : number|string, input2: number|string) {
  const result = input1 + input2; // IDE 상 에러 발생
  return result;
}

위 코드는 에러가 발생한다. ts는 union type으로 여러 자료형이 들어오는 것까지는 알 수 있지만 그 자료형들이 각각 + 연산을 수행할 수 있는지는 모른다. 따라서 컴파일 단계에서 더 나아가 런타임 단계에서 한번 더 세부적으로 체크해줘야 한다.

function combine(input1 : number|string, input2: number|string) {
  let result;
  if(typeof input1 === 'number' && typeof input2 === 'number) {
  	result = input1 + input2;   
  } else {
   	result = input1.toString() + input2.toString(); 
  }  
  return result;
}

유니언 타입을 사용하면 매개변수를 보다 유연하게 사용할 수 있어 편리하다!

리터럴 타입

고정된 특정 값을 리터럴이라고 칭한다. 가령, 특정 문자열만 입력되어야 하는 시나리오가 있을 때 enum을 사용해도 좋지만 보다 코드를 간단하게 사용하기 위해서 리터럴 + 유니언 조합으로 사용하면 편리하다.

function combine(
 input1 : number|string, 
 input2: number|string,
 resultConveersion: 'as-number' | 'as-text' // 이 문자열 2개만 허용
) {
  let result;
  if(typeof input1 === 'number' && typeof input2 === 'number' || resultConversion == 'as-number') {
  	result = +input1 + +input2; // parseFloat() 사용해도 ok. 간단하게 number로 형변환해주는 + 연산자
  } else {
   	result = input1.toString() + input2.toString(); 
  }  
  return result;
}

alias (type)

type 키워드를 사용하여 별칭으로 저장하고자 하는 타입을 설정해줄 수 있다.

type Combinalbe = number | string;

또한 object 타입에도 별칭 지정이 가능하다

type User = { name: string; age: number };
const u1: User = { name: 'Max', age: 30 }; // this works!

따라서 코드의 불필요한 반복을 피할 수 있다.

type User = { name: string; age: number };
 
function greet(user: User) {
  console.log('Hi, I am ' + user.name);
}
 
function isOlder(user: User, checkAge: number) {
  return checkAge > user.age;
}

함수와 반환 자료형

  • void : 값을 반환하지 않는 함수
function printResult(num: number): void {
  console.log("Result : " + num);
}

다만 주의할 점은, 위 함수를 다시 한번 콘솔에 찍는 경우 undefined가 출력된다는 것이다. 실제로는 잘 사용되지 않으나, ts에서 undefined는 실제 값을 반환하지 않을 때 사용할 수 있다. 따라서 다음의 코드를 작성할 수 있다. (잘 사용X)

function printResult(num: number): undefined {
  console.log("Result : " + num);
  return; // 아무것도 반환X -> undefined 반환
}

함수 타입

  • Function : 변수가 함수임을 알려주는 자료형
let combineValues:Function;
combineValues = add;
combineValues = 5; // 컴파일 에러
  • 함수 타입 : 함수의 매개변수, 반환값에 관련된 내용을 설명. (Function 키워드만으로는 컴파일 시 에러를 잡기가 어려움!)
let combineValues = (a:number, b:number) => number;
combineValues = add;
combineValues = printResult; // 컴파일 에러

함수 타입과 콜백 함수

콜백 함수는 자신이 전달되는 인수가 반환 값을 기대하지 않는 경우에도(void) 값을 반환할 수 있다. 따라서 다음의 코드는 에러가 발생하지 않는다.

function sendRequest(data: string, cb: (response: any) => void) {
  // ... sending a request with "data"
  return cb({data: 'Hi there!'});
}
 
sendRequest('Send this!', (response) => { 
  console.log(response);
  return true;
 });

unknown 타입

  • unknown : 어떤 값이든지 들어올 수 있지만, 자료형을 추정하지는 않는다.추가적인 타입 검사를 한 뒤 그 값을 고정된 변수에 할당할 수 있으므로 any보다는 나은 자료형이라고 볼 수 있다. 어떤 타입을 저장할지 정확히는 알 수 없으나 추가적인 검사를 하여 어떤 작업을 수행할지 명시한다.
let userInput: unknown;
let userName: string;
userInput = 5;
userInput = "1000yj";
if (typeof userInput === 'string'){
  userName = userInput;
}

never 타입

아무것도 반환하지 않는 타입. void와는 다르다! (함수의 리턴형을 void라고 적어준 뒤 값을 반환해도 아무런 에러도 발생하지 않음)

function generateError(msg: string) {
  throw {message: msg};
}
generateError("Error occured!");

위 함수는 아무 값도 반환하지 않는다. 따라서 아무것도 반환하지 않는 함수의 경우 :never를 명시적으로 설정해줄 수 있다. (위 코드에 마우스를 올려보면 IDE는 반환형이 void라고 추론한다)

profile
함께 일하고 싶은 개발자가 되기 위해 노력합니다. 코딩테스트 관련 공부 및 이야기는 티스토리에도 업로드되어 있습니다.

0개의 댓글