TypeScript

TypeScript 개념 및 기초

에밀오구 2023. 8. 10. 15:54

TypeScript의 개념과 등장배경

? JS(javaScript) 기반에서 고정된 타입(정적타입) 문법을 추가한 컴파일 언어입니다. 타입이 자유자재로 바뀔 수 있는 JS에서 타입을 자유자재로 변경하지 못하도록 빡빡하게 만든 언어가 바로 타입스크립트(TypeScript)라고 할 수 있습니다.

 왜 JS보다 더 엄격한 타입스크립트가 그 이후에 나왔을 까요? 왜냐하면 에러발생률을 현저히 줄일 수 있기 때문입니다. JS는 타입지정이 동적이라 매번 타입을 써줄 필요가 없기 때문에 누구보다 빠르게 남들과는 다르게 코드를 작성할 수 있는 장점이 있습니다. 하지만  빠르게 프로그래밍을 하다 보면 종종 다른 타입을 함께 연산하는 실수가 생기곤 합니다.타입지정이 자유롭기 때문에 런타임까지 타입에 대한 결정을 끌고 갈 수 있습니다. 그렇게 되면 Type Error가 날 때  런타임 환경 단계까지 동작해야지만 Type Error를 확인해야하는 문제가 발생합니다. 번거롭죠.  또 실행 도중 변수에 예상치 못한 타입이 들어와 Type Error를 발생시킬 수 있었습니다. 이러한 동적타입이 갖는 문제는 개발자들의 마음을 불-편하게 했습니다. 그래서 타입스크립트가 탄생한 것이죠. 타입스크립트는 타입 즉, 자료형을 컴파일 시에 결정하는 것이 큰 특징입니다. 변수를 생성할때마다 매번 타입을 써줘야 하지만 런타임 환경 이전 단계인 개발 코드 작성 단계에서 부터 타입 오류를 확인할 수 있기 때문에  코드를 작성할 때 발생하는  Type Error 를 현저히 줄일 수 있었습니다. 야호! 

 

JS(javaScript)와 TS(TypeScript)

언어 타입 타입 오류 확인 경로
JS 자유로움(동적) 런타임 동작 단계
TS 고정됨(정적) 코드 작성 단계

TS ===  컴파일언어

브라우저나 Node.js 환경은  타입스크립트를 직접적으로 동작시킬 수 없습니다. 그래서 TS는 타입스크립트 컴파일러를 통해  JS로 변환(컴파일)과정을 거친 후에야  브라우저나 Node.js 환경에서 동작할 수 있습니다. 그리고 또한 Typescript의 컴파일은 거의 같은 수준의 추상화를 가진 다른 언어 즉 JS로 변환하기 때문에 엄밀히 말하면 트랜스파일입니다.  *컴파일 ⊃ 트랜스파일  

 주의! TS 컴파일시 에러가 있으면 컴파일이 안될 것 같지만 문제없이 자바스크립트로 변환이 됩니다. 타입스크립트 에러 타입 검사와 컴파일은 별개로 작동합니다. 물론 변환이 된 js 파일은 제대로 동작이 어렵겠지만요!

TS는 javaScript의 슈퍼셋

TypeScript는 javaScript의 모든 기능을 포함하면서, 다른 기능까지 포함하도록 향상 또는 확장된 상위개념인 슈퍼셋임으로 완벽하게 호환됩니다. 

타입스크립트 문법 

let isShow:boolean = true;
let number1:number =0.5;
let firstName:string ="coding";
//배열 
//1 번째 방법 
let items :string[] =["apple", "a", "grape"];
//2 번째 방법: 제네릭 
let numberList :Array<number> =[4,7,100];

배열 타입은 기본적으로 하나의 타입만 작성하게 되어 있습니다. 

튜플 타입(Tuple Type)

요소의 타입과 개수가 고정된 배열을 표현할 수 있습니다.

let user:[string,number,boolean]= ["kimcoding",20,true];

객체 타입(Object Type)

원시타입이 아닌 타입, typeof 연산자를 사용했을 때 "Object"를 변환하는 모든 타입을 말합니다. 

*원시타입으로 number,string,boolean, undefined, null, symbol 이 있습니다. 

let obj:object={};

let user:{name:string, age:number}={
	name: "kim",
	age:20
};

Any 타입

any 타입은 변수에 값을 재할당하는 경우 타입을 명시한 변수와 달리 값을 재할당할 수 있습니다. 그래서 실제 할당된 값의타입이 가지지 않는 메서드 및 프로퍼티로 접근해도 에러가 나지 않습니다. 대신, 반환되는 값은 undefined로 나옵니다. 

let maybe: any =4;

console.log(maybe.length);
//실제 할당된 값 4의 타입(number 타입)이 갖지 않는 length 메서드로 접근해도 에러가 발생하지 않으며 
//undefined로 반환되어 출력됩니다.

let list: any[] = [1,true,"free"];

list[1] = 100;
//any 이므로 다른 타입으로 재할당이 가능합니다.

함수 타입지정 

함수를 표현할 때는 매개변수의 타입과 리턴값의 타입을 명시해야 하나, 리턴 값은 *타입추론을 이용해 생략 가능합니다. 그리고 함수에 리턴 값이 없다면, void 를 사용해 작성할 수 있습니다.  주의! TS 는 JS 와 달리 매개변수의 개수에 맞춰 전달인자를 전달해야 합니다.  전달인자보다 매개변수가 많으면 에러가 발생하며 매개변수를 전달인자보다 적게 선택적으로 받고 싶다면 매개변수의 이름끝에 물음표(?)를 붙여 선택적으로 받을 수 있습니다.  그리고 당연하게도  매개변수에 물음표와 default parameter를 같이 사용할 수 없습니다. 

function add(x:number,y :number) :number{
	return x+y;
}
//타입 추론
function add(x:number,y :number){
	return x+y;
}
//void 사용
function print =():void=>{
	console.log("리턴값이 존재하지 않으므로 타입을 void로 지정합니다.");
}

let greeting = (firstName: string, lastName: string): string => {
	return `hello, ${firstName} ${lastName}`;
}

//에러가 납니다.
greeting('coding');

//정상적으로 작동합니다.
greeting('coding', 'kim');

//너무 많은 매개변수를 보내 에러가 납니다.
greeting('coding', 'kim', 'hacker');

let greeting = (firstName: string, lastName: string ="kim"): string => {
	return `hello, ${firstName} ${lastName}`;
}

//정상 작동. 
greeting('coding');

//정상 작동. 뒤의 인자로 undefined를 보내도 값은 “hello, coding kim”으로 반환
greeting('coding', undefined); //hello, coding kim

let greeting = (firstName: string, lastName?: string): string => {
	return `hello, ${firstName} ${lastName}`;
}

//정상적으로 작동하지만 lastName의 값을 넘겨주지 않아 undefined로 반환됩니다.
greeting('coding'); //hello, coding undefined 

//정상적으로 작동합니다.
greeting('coding', 'kim');//hello, coding kim

//너무 많은 매개변수를 보내 에러가 납니다.
greeting('coding', 'kim', 'hacker');

매개변수에 물음표와 defaul t parameter를 같이 사용할 수 없습니다.

유니온 타입(Union type)과 인터섹션 타입 (Intersection type)

유니온 타입은 | 연산자를 이용하여 자바스크립트의 OR 연산자, 즉 "A타입 이거나 B타입이다."라는 의미의 타입을 표현할 수 있습니다. 유의!  유니온 타입인 값이 있으면, 유니온에 있는 모든 타입에 공통인 타입만 접근 가능합니다. 타입스크립트는 공통되고 보장된 프로퍼티만 제공해야하기 때문인데 나머지 프로퍼티에도 접근하고 싶다면 *타입 가드를 사용해야 합니다. 

interface Developer {
  name: string;
  skill: string;
}

interface Person {
  name: string;
  age: number;
}
//Developer 와 Person을 유니온타입으로 받는 someone 매개변수
function askSomeone(someone: Developer | Person) {
//함수내에서 Developer 와 Person의 공통 타입인 name 만 접근 가능하여 사용할 수 있습니다.
	console.log(someone.name);
}
//타입가드를 적용한 예제 
//타입 가드(Type Guard)란? TypeScript에서 타입을 보호하기 위해 사용되는 기능 중 하나입니다. 타입 가드는 특정 코드 블록에서 타입의 범위를 제한해 해당 코드 블록 안에서 타입 안정성을 보장해 줍니다.
function askSomeone2(someone: Developer | Person) {
  // in 연산자 : 타입스크립트에서 객체의 속성이 존재하는지를 체크하는 연산자
  // in 연산자는 객체의 속성 이름과 함께 사용하여 해당 속성이 객체 내에 존재하는지 여부를 검사
  if ('skill' in someone) {
    console.log(someone.skill);
  }

}

인터섹션 타입(Intersection Type )은 & 연산자를 사용하여  자바스크립트의 && 연산자, 즉 "A타입이고 B타입이다."라는 의미입니다. 전달인자를 전달할 때 모든 프로퍼티를 전부 보내줘야 함으로 모든 프로퍼티에 접근 가능합니다. 

 

*컴파일 : 한 언어로 작성된 소스 코드를 다른 언어로 변환하는 것. 꼭 고수준의 언어를 저수준언어로 변환하는 것이 컴파일이 아니며 한 언어로 작성된 코드를 다른 언어로 옮기는 일을 통칭합니다. 

* 트랜스파일 : 한 언어로 작성된 소스 코드를 비슷한 수준의 추상화를 가진 다른 언어로 변환하는 것을 말합니다. 트랜스파일 은 컴파일 개념에 포함되는 좁은 개념입니다. 컴파일 ⊃ 트랜스파일  

 

*타입추론: 타입을 지정하지 않아도 TypeScript 컴파일이 스스로 판단하여 타입을 넣어주는 것을 말합니다. 

 

출처 

https://inpa.tistory.com/entry/TS-%F0%9F%93%98-TypeScript-%EC%86%8C%EA%B0%9C-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95-%EC%B4%9D%EC%A0%95%EB%A6%AC-tsconfig