1. 타입스크립트의 기본 타입과 변수선언 그리고 제어문

백승일·2020년 10월 10일
0

타입스크립트

목록 보기
2/5

저번에 기본적인 설정을 끝냈구 이제 본격적으로 이론공부 시작이다. 주니어 개발자라 이것도 해야하지않나 저것도 해야하는데 라는 불안한 마음이 가아아아아득 하지만 하나하나 천천히 해나가보자. 일단 타입스크립트 끝내고 SSR,웹표준,성능 개선 등을 공부해볼 것이다.

타입 검사, 타입 선언

언어에 따라 타입 검사는 크게 동적 타입 검사, 정적 타입 검사로 구분된다. 그래서 정적언어, 동적언어 라고도 부르는데, 정적언어는 c같은 애들, 동적언어는 자바스크립트 같은 애들을 말한다.

반면 타입 스크립트는 점진적 타입 검사를 수행한다고 한다. 이검사는 컴파일 시간에 타임 검사를 수행하여 필요에 따라 타입 선언을 생략하는 걸 허용한다. 생략하게 되면 암묵적 형변환이 일어나게 된다. 예를 들어

function add(a){
  return a +10;
}
add(10);

이런 코드가 있다면 매개변수 a에 타입을 지정하지 않았지만 타입스크립트 컴파일러는 에러를 내지 않는다.

자바스크립트의 경우 동적으로 타입을 검사하기 때문에 암묵적으로 형변환이 일어난다. 때문에 타입을 보장해주는 방어코드를 써야할 때도 존재한다. 타입스크립트를 사용하는 또 하나의 이유가 아닐까 생각이 든다.

타입 계층도

타입스크립트는 점진적 타입검사를 수행하기 때문에 타입의 생략뿐 아니라 암시적 형변환, 타입 결함을 통해 새로운 타입을 정의할 수 있다.

-출처 : https://mishka.kr/2020/03/18/TypeSctipt-3-var/

계층도의 최상단에는 any타입이 존재하고 그 아래로 기본 타입, 객체 타입,기타 타입 이 존재한다. 간단히 봐보자

기본 타입

기본타입이라함은 내장타입으로 타입스크립트에서는 다음 종류의 기본 타입을 지원한다.

  • string, number, boolean
  • symbol
  • enum
  • 문자열 리터럴

기본 타입 중 string, number, boolean은 문자열, 숫자, 불리언 값을 다룰 때 사용한다.

문자열의 경우 타입스크립트 가이드에선 큰 따옴표 사용을 권장하지만 작은 따옴표, 백틱도 가능하다.
숫자의 경우 10진수 뿐 아니라 2, 8 ,16진수를 지원한다.
불리언은 true혹은 false만 할당 가능하다.

symbol은 Symbol()함수를 이용하여 생성할 수 있는데, 고유하고 수정 불가능한 데이터 타입으로 객체 속성의 식별자로 사용된다.

enum은 number의 확장 타입으로 첫 번째 enum요소엔 0이 값으로 할당되고 다음 값은 초기화 하지않는 이상 1 증가된 값이 된다.

enum Day = {mon,fri,sun};
let date:Day = Day.mon; /// 0

문자열 리터럴은 string타입의 확장 타입으로 사용자 정의 타입에 정의한 문자열만 사용할 수 있다.

type Events = "mouse"|"keyboard";
const event:Events = "mouse"

객체 타입

객체 타입은 속성을 포함하고 있다. 그 종류는 다음과 같다.

  • Array : 배열 요소에 대응, 배열 아이템의 타입에 따라 타입[] 이런 식으로 선언
  • Tuple: 배열 요소의 갯수가 제한되어 있을 때, 요소별로 타입을 지정한 타입, 때문에 그 순서와 갯수가 맞아야한다.
  • Function
  • 생성자
  • class
  • interface
    나머지는 나중에 깊게 알아보자

기타 타입

  • 유니언 : 2개 이상의 타입을 하나의 타입으로 정의한 타입이다. string|number;
  • 인터섹션 : 두 타입을 하나로 합쳐서 만드는 타입
interface maplestory{type:"rpg"}
interface suddenattack {view:"3d"}
let eternalCity: mapleStory & suddenAttack={type:"rpg",view:"3d"}
  • 특수타입
    - Void : 함수의 반환값이 없을 때, 빈 값을 나타낼 수 있는 타입
    - null : 빈 책체로 초기화
    - undefined : 초기화 되지 않는 값

변수에 타입 지정

타입스크립트로 타입을 지정하려면 이런 형식으로 작성해야한다.

let 변수:타입 =

자바스크립트의 타입

타입스크립트에서는 자바스크립트의 내장 타입을 제공한다. 크게 기본 타입, 객체 타입, 함수 타입이 있다.

자바스크립트 내장 타입

자바스크립트 내장타입으로는 boolean, number, string, symbol이 있다. 그 외에 null, undefined, function, object가 존재한다. 자바스크립트는 타입 지정에 있어서 런타임에 값 할당과 동시에 동적으로 타입이 결정 된다. symbol의 경우 es6에서 추가된 타입이다.

  • symbol 타입 : 객체 속성의 유일하고 불변적인 식별자 역할로 사용된다.
const hello = Symbol("hello")

Symbol함수는 심볼 객체를 반환하는데 인수는 심벌의 설명을 의미하며 접근할 때 사용할 수 있고 생략할 수도 있다.

let hello = Symbol("hello");
let hello2 = Symbol("hello");
console.log(hello === hello2); /// false

이 처럼 심벌 객체는 호출 될 때 마다 새로운 객체를 반환한다.

const uniqueKey = Symbol();
let obj = {};
obj[uniqueKey] = 1234;
console.log(obj[uniqueKey]) /// 1234

이렇게 객체의 유일한 식별자로 사용할 수 있다.

  • enum 타입

enum타입은 es6에 제안된 타입으로 컴파일 시간에 평가되는데, 숫자 상수의 집합을 정의 할 때 사용한다. 선언 형식은 다음과 같다

  • enum 변수명 {속성:값, 속성:값 ...};

이때 값은 생략 가능하며 생략시에 첫 번째 인덱스에 0이 할당되고 이후에 1씩 더해져서 할당된다. enum선언시 const 키워드를 붙여서 상수 enum으로 만들 수 있는데, 이 상수 enum은 읽기 전용이 된다. 이때 몇 가지 제약이 있다. 값에 접근할 때 아래와 같은 제한이 있다.

const enum WeekDay {Mon,Tue=2,Wen=2*2}; ///생략시 첫 인덱스는 0, 식도 할당가능하다
let day1 = WeekDay.Mon ///0 가능
let day2 = WeekDay["Mon"] ///0 가능
let day3 = WeekDay[WeekDay.Tue]  /// 불가능 인덱스 접근 방식일 땐 문자리터럴만 사용해야한다.
let day4 = WeekDay /// 불가능 enum식별자는 직접 할당할 수 없고 속성이나 인덱스로 접근해야함

enum은 문자열도 할당할 수 있다. 단 이때엔 다른 속성의 초기값도 문자열 또는 숫자가 와야하며 연산식은 할당할 수 없게 된다.

const enum WeekDay {Mon="monday",Tue="two",Wen=2*2}; /// Wen오류 연산식 불가
let day1 = WeekDay.Mon ///
let day2 = WeekDay["Mon"] ///
let day3 = WeekDay[WeekDay.Tue]  /// 

또 다른 enum의 특징은 숫자 value를 가진 속성은 키가 값이 되기도 한다는 점이다.

enum WeekDay{Mon, Tue=12, Wen=3};
console.log(WeekDay);
///{ '0': 'Mon', '3': 'Wen', '12': 'Tue', Mon: 0, Tue: 12, Wen: 3 }

단 문자열을 초기값으로 준 경우 값으로 키를 알수 없다. 이렇게 값과 키가 서로 바뀌는 것을 리버스 매칭이라 하며 때문에 숫자 enum에 할당되는 속성은 해당 객체의 속성보다 2배 더 많게 된다.

이 enum을 타입으로 선언하고 변수 할당할 때에도 제약이 있는데, 아래의 예를 보자

enum WeekDay{Mon, Tue=12, Wen=3};
let myDay :WeekDay = true /// 불가능 	

enum을 타입으로 선언 할 경우 enum의 초기값이 될 수 있는 숫자와 문자열만 할당 가능하며, 모든 초기값이 문자일 경우 문자열 이나 숫자를 할당할 수 없다.

타입스크립트 내장 타입

any

any타입은 제약없는 타입으로 어떤 타입의 값이든 받을 수 있다. 때문에 타입의 결과를 예측할 수 없을 때 유연한 대처가 가능하다.

let num : any = 10;
num = "hi";
console.log(num); /// "hi"

any타입은 모든 타입의 최상위 타입으로 자바스크립트의 모든 타입을 할당 받을 수 있습니다.

let num; /// let num:any 와 동일

자바스크립트의 타입을 선언하지 않은 변수 선언과 마찬가지로 any는 어떤 타입의 값이 든 받을 수 있는데, 이는 any타입으로 선언된 변수는 런타임시에 최소한의 정적 타입 검사만 수행하기 때문이다.

이 둘 사이에는 차이가 있는데, 선언되지 않은 임의의 메소드를 호출한다면 타입선언하지 않은 변수는 컴파일 시 에러를 내지만 any타입을 받은 변수는 오류를 내지 않는 차이점이 있다.

  • tsconfig의 any설정
    any타입의 경우 느슨하기 떄문에 생략할 수 있지만, 그래도 명시적으로 적어주는 것이 명확함으로 tsconfig.json파일의 noImplicitAny옵션을 true로 설정하면 any타입을 생략했을 때 컴파일 오류를 내준다.

object

object 타입도 any와 마찬가지로 타입 구분 없이 값을 할당 받을 수 있는 타입이다. 하지만 any와 큰 차이점이 있는데 바로 타입 검사 시점이다. any의 경우 타입 검사를 런타임에 하지만 object의 경우 컴파일 시에 검사를 하기 때문에 앞서 실험해본 선언되지 않은 메소드 호출을 해보면 컴파일 시 에러를 발생시킨다.

배열과 제네릭

배열은 여러 값을 하나의 변수에 담아 관리하는 자료구조로 타입스크립트에는 2가지 형태로 나눌 수 있다.

  • 배열 타입
    배열 타입은 배열 요소의 타입에 따라 선언된다.
let array : 요소타입[] = [요소]; 
let emptyArray : string[] = []; emptyArray.push("ㅎㅎ");
let numArray : number[] = [1,2,3,4,5];
let stringArray : string[] = ["아","으아","으아으아으아"]

배열의 요소가 정해지지 않았다면 any를 사용할 수도 있겠지만 유니언 타입을 사용하는 게 더 좋아보인다.

let array : (number|string|boolean)[] = [1,"오우야",true]; 
  • 제네릭 배열 타입
    제네릭 타입도 배열 타입과 비슷한데, 큰 차이가 있다. 일단 이런게 있다 정도로만 넘어가보자.
let array : Array<요소타입> = [요소]; 
let arrayBox : Array<string|number> = ["안녕","잘지내니",486]; 
let callBackArray : Array<()=>string> = [()=>"짜잔"];
/// 제네릭 타입은 객체 타입도 받을 수 있다.

튜플 타입

튜플 타입은 요소의 갯수가 정해진 배열에 대응하는 타입을 말한다. 배열의 경우 요소 갯수 제한 없이 사용할 수 있지만, 튜플의 경우 요소에 대응하는 타입이기 때문에 타입의 순서와 갯수가 요소와 정확히 일치되어야한다.

let array : [0번째 인덱스 요소 타입,1번째 인덱스 요소 타입] = [요소,요소]; 

void, null,undefined

  • void : 함수 반환값이 없을 때 지정하는 타입으로 void타입에는 null이나 undefined만 할당할 수 있다. void가 null과 undefined의 상위 타입이기 때문이다.
function funq(){
	console.log("마마~")
}

이렇게 반환 값이 없는 함수의 값으로 void타입을 지정해준다.

function funq() :void{
	console.log("마마~")
}

void타입은 결국 null이나 undefined밖에 할당 받지 못한다. 대부분의 경우 이런 값을 사용하지 않을 때가 많기 때문에 null이나 undefined를 할당할 경우 에러를 내주는 ts설정이 존재한다. "compilerOptions"에 "strictNullChecks"옵션이다. 값을 true로 줄 경우 null이나 undefined를 변수에 할당할 수 없다. 또 null의 경우 typeof 검사시 object로 나오기 때문에 undefined를 사용하는 것을 권장한다.

제어문

타입스크립트도 자바스크립트처럼 조건문을 사용할 수 있다. 대표적으로 if문과 switch문이다.

조건문의 타입 제약

  • if문
    자바스크립트와 다를 것이 없다. 하지만 조건문에 사용할 변수도 타입지정을 해줘야한다.
  • switch문
    자바스크립트의 switch문과 똑같다. 단 fall through를 컴파일시에 방지할 수 있는데, tsconfig.json파일에 noFallthroughCasesInSwitch옵션을 통해서 폴 스루 설정이 가능하다.

반복문

타입스크립트가 지원하는 반복문들을 살펴보자

일반 for문

타입스크립트에서도 일반 for문은 자바스크립트와 형식은 같다. 다른 점이라 한다면 순회하는 변수의 타입을 지정해주는 정도 이다.

for(let i:number=0; i <5 ; i++){}

for-in, for-of문

for-in문의 경우 es5에서 배열이나 객체를 순활 할 때 사용한다.

let names = { "A": "승일", "b": "민지" };
for (let i in names) {
    console.log(i,names[i]); /// A,승일 B,민지
}

for of의 경우 반복가능한 이터러블 객체를 이용하여 순환하는 반복문이다. 좋은 설명글이 있어서 링크를 걸었다.

let names = ["승일","민지"];
for (let i of names) {
    console.log(i); /// 승일 민지
}

일반적인 이터러블 객체인 문자열, 배열 등 을 타입스크립트 target속성을 ES5로 설정하고 for-of문으로 돌리는건 문제가 되지 않는다. 하지만 ES6문법인 map과 set으로 for-of문을 사용하려면 target을 ES2015로 수정해줘야한다.

while , do-while

타입스크립트의 while문과 do-while문은 자바스크립트 es5와 동일한 문법을 사용한다.

let count : number = 0;
let sumed : number = 0;
while(count <=100){
  sum +=count
  count++;
}
let mind = 0;
do{
  console.log(mind);
	mind++
}(mind != 10)
profile
뉴비 개발자

0개의 댓글