TypeScript 개념 및 기초
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');
유니온 타입(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 컴파일이 스스로 판단하여 타입을 넣어주는 것을 말합니다.
출처