[TypeScript] 타입스크립트란? 타입스크립트의 타입들!

김발자·2022년 6월 19일
post-thumbnail

❓TypeScript 란

  • 타입스크립트는 자바스크립트에 타입을 부여한 언어이다. 자바스크립트의 확장된 언어
  • 브라우저에서 바로 실행할 수 없고 컴파일을 통해 자바스크립트로 변환해주어야한다.

✔️ 타입스크립트의 특징

  • 각 변수나 상수에 type을 지정할 수 있다.

  • 자바스크립트에 추가 기능을 제공한다. (Javascript Superset)

  • 개발 중 런타임 에러를 파악할 수 있도록 추가적인 오류 검사를 제공한다.

  • 타입을 직접 생성할 수 있다.

    => 자바스크립트 코드를 좀 더 논리적으로 표현할 수 있다.

✔️ 왜 사용하는 걸까?

  • 코드에 논리적인 오류를 줄이기 위해서이다. (ex. 문자열을 더하기 연산자를 사용하면 문자열이 붙어서 나오는 오류 )
  • 타입스크립트를 사용하면 자바스크립트를 사용할 때보다 개발자의 의도대로 정확히 코딩되었는지 확인할 수 있다.

✔️ 설치하기

Node.js를 다운받고 아래 코드를 실행한다.

Node.js 다운받기

sudo npm install --location=global typescript

🎯 TypeScript의 타입들

✔️ core types : number, string, boolean

typedesc
number실수, 정수 모두를 포함
string문자열, 백틱 문자열
booleantrue, false not means Truthly or Falsy

➕ 타입 추가하는 법

예를 들어 아래와 같은 코드가 있다고 치자.

const add = (n1,n2) => {

	return n1 + n2;

}

const number1 = '5';

const number2 = 2.8;

const result = add(number1,number2);

console.log(result)

결과는 52.8 일 것이다. 이건 우리가 원하는 결과는 아니다.

아래처럼 타입스크립트를 사용하면 함수 파라미터에 타입을 추가해줌으로써 논리적 오류를 피할 수 있다.

const add = (n1:number,n2:number) => {

	return n1 + n2;

}

const number1 = '5';

const number2 = 2.8;

const result = add(number1,number2);

console.log(result)

타입을 추가하는 방법은 파라미터 옆에 :{type} (클론 + 타입) 을 넣어주면 된다!

❗️주의사항

  • IDE 에서 js 파일과 ts 파일을 같이 열면 에러가 발생한다.
  • 타입스크립트에서 원시타입은 항상 소문자이다.

➕ 자바스크립트에서도 타입을 확인할 수 있다.

const whatatype = 3
console.log(typeof whatatype);

위와 같이 자바스크립트에서도 타입은 확인할 수 있다. 단, 런타임 중에 확인된다.
하지만 타입스크립트는 컴파일되는 과정에서 확인되기 때문에 에러를 미리 방지할 수 있다.

➕ 왜 저기는 타입을 추가하고 여기는 추가하지 않을까?

const add = (n1:number,n2:number,test: boolean,pharse:string ) => {

	if(test){
		
		const result = n1 + n2
		
		console.log(pharse + result)
	
	} else {
	
		return result;
	
	}

}

  

const number1 = 5;

const number2 = 2.8;

const printResult = true;

const resultPharse = 'Result is:'

  

const result = add(number1,number2,printResult,resultPharse);

const 는 상수이기 때문에 타입스크립트는 처음 상수 값을 입력할 때 타입이 자동으로 지정된다. 값이 변하지 않기때문에 따로 지정할 이유가 없다.

그렇다면 let 은 어떨까? 동일하다. 처음으로 작성한 값의 타입으로 지정된다.
정한다면 아래와 같이 작성할 수 있다.

let number1:number = 5

하지만 굳이 작성하지않아도 타입스크립트가 스스로 타입을 완벽하게 추측하여 지정하기 때문에 지정해 줄 필요는 없다.

하지만 선언문만 작성된 경우에는 타입을 지정해야한다.

let number1:number;

✔️ core types : Object

typedesc
objectex. {age: 30} 키와 값으로 구성된 객체.

예를 들어 아래와 같은 코드가 있다고 하자.

const person = {

name: 'eunji',

age: 23

}

타입스크립트는 person 을 단순히 object 타입을 지정하지않고 안에 정의된 property 의 타입까지 추론하여 정의한다.

직접 타입을 정의하고 싶다면 아래와 같이 정의해주어야한다. (물론 좋은 방법은 아님)

const person: { // {} 은 object라는 뜻

	name: string;
	
	age: number; // ! 타입이 아닌 특정값을 입력하면 그 값만 가질 수 있음

} = {

name: "kimveloper",

age: 23,

};
  • 중첩 객체
  const product = {
	  id: 'abc1',
	  price: 12.99,
	  tags: ['great-offer', 'hot-and-new'],
	  details: {
	  title: 'Red Carpet',
		  description: 'A great carpet - almost brand-new!'
	  }
  }

	// 이렇게 타입이 지정된다.
	//  {
	//  id: string;
	//  price: number;
	//  tags: string[];
	//  details: {
	//  	title: string;
	//  	description: string;
	//  	}
	//  }

✔️ core types : Array

typedesc
objectex. [1,2,3] 타입이 유연하게 정의될 수도 있고 별도로 지정될 수도 있음

타입이 고정된 배열

let favoriteACtivities: string[];

favoriteACtivities = 'sports' // error
favoriteACtivities = ['sports'] // correct

타입이 유동적인 배열

let favoriteACtivities: any[];

favoriteACtivities = ['sports',2, { food:'cake'}] // correct!
let favoriteACtivities: (string | number) [];

favoriteACtivities = ['sports',2 ] // correct!

타입스크립트를 사용하면 좋은 이유 하나 더! 각 타입에 맞는 메소드를 사용할 수 있다!

✔️ core types : Tuple

typedesc
tuppleex. [1,2] 길이와 타입이 고정된 배열

만약, 첫번째는 무조건 숫자이고 두번째는 무조건 문자 타입인 2개의 객체로 이루어진 배열을 만들고 싶다면 튜플을 사용하면 된다.

❗️ 주의할 점은 push() 등 Array 메소드는 사용해도 에러가 발생하지 않는다는 점이다.

let myHobbies:[number,string];

myHobbies[0] = '1' //error!
myHobbies[0] = 1 // correct
myHobbies[3] = 1 // error!

myHobbies.push('2') // correct?

✔️ core types : Enum

typedesc
Enumex. enum{New,Old} 정의된 변수만 사용할 수 있는 객체

만약 0은 관리자, 1는 읽기전용, 200는 작가 계정 으로 표현하고 싶다면 이 타입을 사용하면 된다.

enum 타입은 무조건 첫글자를 대문자로 사용해야한다.

enum Role{ ADMIN, READ_ONLY, AUTHOR};

  

const User = {

	name: "eunji",
	
	age: 23,
	
	hobbies: ['Sports','Cooking'],
	
	role: Role.ADMIN

};

  

if(person.role === Role.AUTHOR){

console.log('is AUTHOR')

}

// result : none

정의는 문자로하고 표현은 숫자로 하고 싶다면 아래와 같이 할 수 있다. (꼭 숫자가 아니여도 다른 문자로도 표현할 수 있음)

enum Role{ ADMIN, READ_ONLY = 100, AUTHOR = 200};

  

const person = {

	name: "eunji",
	
	age: 23,
	
	hobbies: ['Sports','Cooking'],
	
	role: Role[0]

};


if(person.role === Role[200]){

	console.log('is AUTHOR')

}

✔️ core types : ANY

typedesc
anyex. * 모든 타입을 사용할 수 있음

any 타입을 사용할 경우, 타입스크립트 컴파일러는 작동하지 않는다. (검사할 것이 없기때문)

✔️ Combine Type : 조합된 타입

아까봤던 타입이다. 예시는 두 개뿐이지만 그 이상도 가능하다.

let id:string | number;

id ='kimveloper'; // correct

id = 909; // correct

id = true // error!

✔️ Literal Type : 고정된 값

이것 또한 아까 예시에서 찾아볼 수 있었다.

const 의 경우, 값이 변하지 않기 때문에 입력된 값 자체가 타입이 된다.

아래 두 변수를 비교해보자.

const name = 'kimveloper' // const name: 'kimveloper'

let age = 1; // let age:number

이렇게도 활용할 수 있다. 들어온 게스트가 관리자인지 확인하는 함수가 있다고 치자.

function checkAdmin(field: 'Admin' | 'User'){
	if(field === 'Admin'){
		console.log('Hi Admin');
	}
}

  

const guest1 = 'Admin'

const guest2 = 'User'

const guest3 = 'Unknown';

  

checkAdmin(guest1);

checkAdmin(guest2);

checkAdmin(guest3); // error!

함수의 파라미터 값을 리터럴 타입으로 정의해서 일반 유저나 관리자가 아닌 사람을 걸러낸다.

물론 enum 도 사용할 수 있다.

✔️ Type Alias - 사용자 정의 타입

자주 사용하는 타입들은 타입 알리아스 로 타입을 직접 생성해서 코드를 더 간단하게 만들 수 있다.

타입 알리아스를 이용하면 불필요한 반복을 줄이고 타입을 관리하기 쉬워진다.

type Combinable = number | string;

type CoversionDescriptor = 'as-number' | 'as-text';

✔️ Function Return Type - 함수 리턴 타입

함수에서 가장 중요한 타입이 있는데 바로 return 타입이다.

숫자 2개를 인자로 받아 더한 결과를 반환하는 함수를 만들어보자.

const add = (n1:number, n2:number) => {
	return n1 + n2
}

함수의 마우스를 올려보면 :{type} 이 나오는데 리턴값의 타입이다. 여기서는 두 개의 숫자타입 인자를 더해서 리턴했기 때문에 타입스크립트가 자동으로 리턴값을 숫자로 인식했다.

직접 리턴값을 명시하고 싶다면 아래와 같이 쓰면 된다.

if2 예시와 같이 리턴 값을 문자로 수정하면 에러가 발생한다.


function add(n1:number,n2:number): number{

	return n1 + n2;

}


// if2

function add(n1:number,n2:number): string{

	return n1 + n2; // error!

}

위에서 계속 말했듯이 굳이 타입을 명시할 이유가 없다면 타입스크립트가 자동으로 인식하게 하는 것이 좋다.

VOID

만약 아무것도 리턴하지 않는 함수가 있다면 TypeScript는 함수의 리턴 타입을 void 로 인식한다.

const printSomething = (text:string)=>{
	console.log(text)
}

console.log(prinSomething('something')) // JS로 확인해보면 어떤 결과값이 나올까요?

마지막 console.log(printSomething('something') 을 실행하면 JS에서는 undefined로 인식한다. 실제로 TS에서도 undefined 라는 타입이 있으므로 이것으로 리턴 타입을 정의할 수 있다.

하지만 함수의 리턴(return) 구문이 없는 경우, undefined 로 정의하면 에러가 발생한다.

void 타입을 사용하는 것은 개발자가 의도적으로 리턴 값을 넣지 않았습니다. 를 의미한다. 따라서 함수가 리턴(return) 구문을 사용하지 않는다면 void로 써주는 것이 맞다.

undefined 로 리턴 타입을 정의하면 리턴하는 값이 있고 그 값은 'undefined' 이다. 라고 정의하는 것이다.

기술적으로 다르다.


const printSomething = (text:string):undefined => { // error!
	console.log(text)
}

const printSomething = (text:string):undefined => { // correct! but rare case
	console.log(text)
	return;
}

const printSomething = (text:string):void => { // correct! but rare case
	console.log(text)
	return text;
}

void로 타입을 지정한 후 값을 반환해도 상관없다. void 를 사용하면 반환 값에 대한 검사가 이루어지지 않기 때문이다.

✔️ Function Type : 함수 타입 정의하기

변수 someFunc 는 함수만 저장할 수 있다고 해보자. 이 때, 아래와 같이 someFunc의 타입을 Function 으로 지정할 수 있다.

let someFunc:Function; // 대문자!

변수 someFunc무조건 문자 값을 반환해야하는 함수라면 아래와 같이 더 자세히 지정할 수 있다.

// someFunc 는 문자를 반환하는 함수입니다.

let someFunc:()=> stirng; 

변수 someFunc한 개의 숫자 파라미터와 한 개의 문자 파라미터를 받고 문자 값을 반환해야하는 함수라면 아래와 같이 지정할 수 있다.

// someFunc 는 한 개의 숫자 인자와 문자 인자를 받고 숫자를 반환하는 함수입니다.

let someFunc: (a:number, b:string) => string;

✔️ Callback Type : 콜백 함수 타입 정의하기

콜백 함수 타입은 함수 타입을 정의하는 것과 비슷하다.

const someFunc = (num1:number, num2:number, cb:(n:number)=> void) => {

	const result = num1 + num2;
	cd(result);
}

someFunc(5,6,(result)=>{console.log(result)}); // result 11

✔️ Unknown : 알수없음

타입 any 와는 다르다. 개발자가 값이 정말 어떤 타입인지 알 수 없을 경우 사용한다.

unknown 의 경우, 다른 타입이 지정되어 있는 변수에는 할당할 수 없다.

아래 예시를 보자.


let inputValue:unknown;
let textInput: string;


inputValue = 4;
inputValue = 'Developer';

textInput = inputValue; // error!!

하지만 any 타입은 가능하다. any 타입의 경우, 타입스크립트가 타입에 대한 검사를 하지 않기때문이다.


let inputValue:any;
let textInput: string;


inputValue = 4;
inputValue = 'Developer';

textInput = inputValue; // No error...

unknown 의 경우 any 타입보다 더 꼼꼼히 타입을 검사할 수 있으므로 더 낫다고 할 수 있다.


let inputValue:unknown;
let textInput: string;


inputValue = 4;
inputValue = 'Developer';

if(inputValue === 'string'){
	textInput = inputValue; // No error...
}

✔️ Never Type : 절대 안돼~!

never 은 새로 추가된 타입이다. void 와 비슷한데 절대! 리턴 값을 반환하지 않는다는 점에서 다르다.


function errorHandler(message: string, code: number){
	throw { message: message, errorCode: code}
}

errorHandler('Page Not Found',404);
function hanldeError(message: string, code: number): never{

return message; // error!!

}
profile
매일 글적글적 거리고 싶은 김발자

0개의 댓글