나무소리님의 typescript강의를 보고 이해한 내용을 정리한 글입니다.
tsc 의 makefile이다. build시 build할 파일 경로 또는 outDir 경로를 지정할수 있다.
let, const, var으로 변수의 특징을 정할수 있다. c랑 비슷하지만, c의 경우 const만 사용했는데, javascript에서는 let이랑 var가 있습니다.
let과 var의 차이는 let의 경우 여러번 재할당이 가능하다. 아래 처럼 해도 에러가 안납니다. 더 자세한 설명은 링크를 타고 보자.
let a = 'asadf';
let a = 'ewrfdv';
변수를 선언할때 타입을 선언하지 않아도 유추되어 타입이 정해진다.
또한 만약 선언시 타입도 안정하고 값도 초기화도 안하면 그냥 any로 결정된다.
3가지 함수 선언 방법이 있습니다. 일반적으로 선언적 함수 익명함수는 눈에 익지만 람다함수는 많이 안써본 경우가 많습니다.
람다함수를 간략하게 설명하면 람다를 쓰는이유는 가독성이 좋아서 사용합니다. 하지만 문제점이 있습니다.
람다를 쓸경우 this를 사용한다면 유의하라. 아래 예제를 보면 알수 있습니다.
param = 'global param';
let printParam = () => {
console.log(this.param);
}
let object = {
param: 'object param',
func: printParam
}
let object2 = {
param: 'object2 param',
func: printParam
}
object.func();
object2.func();
해당 코드의 출력값은 아래와 같습니다.
global param
global param
이유는 람다의 경우. 선언될떄 this의 값이 확정되는데, object객체를 선언할때 printParam의 this.param의 값도 결정된다. 그래서 object2를 해도 global param이 나온다.
함수 선언시 가변인자를 지원하지 않아서 아래 사진과 같이 오버로딩으로 여러 인자들을 지원하는 방법이 있습니다.
아래 와 같이 아무런 타입없이 파라메터를 선언해도 any가 되는데 이렇게 하는게 문제가 있다고 했다. 그래서 타입을 선언할때는 정확하게 타입을 명시해주자. return값도 마찬가지다.
함수동작중 리턴이 실행되지 않을떄도 잇는데, 이럴때 타입스크립트의 리턴은 never로 한단다.
void와 never 차이 : never는 함수가 종료하지 않아 결코 return하지 않을 때 사용된다. 무한루프 혹은 Error 메시지를 throw할 때 return type이 never이다.
똑같이 유추가 적용됩니다.
자료형중 튜플이 있습니다. 순서대로 들어올 타입을 지정 할 수 있고 순서가 다르거나 다른 타입이 들어오면 에러가 나옵니다.
하지만 인터페이스 사용을 더 선호합니다.
Box클래스를 보세요! 생성자에서 any로 자료형을 선언했습니다. 그래서 box객체를 생성시 Orange 도 받을수 잇고 apple도 받을수 잇고 해당, orange, apple 모두에 있는 getName이나 getBrix호출시 정상 작동합니다 .
문제는 만약 box객체생성시 'Bannana'같은 뜬금없는 문자열이 들어오면 해당 문자열에는 getName같은 매게변수가 없습니다. 하지만 이건 컴파일시 알아차리지 못해 런타임에러에서 에러가 납니다 .
떄문에 에러처리가 어려워집니다. 그래서 우리는 c++의 템플릿과 비슷한 제너럴을 사용합니다.
c++의 템플릿 처럼 box정의가 class Box로 정의 되어잇습니다. 이를 제너럴이라 하는데 이걸 사용하면 앞서 문제가 있던 에러처리가, 만약 'banaba'가 들어오더라도 컴파일 에러에서 잡습니다.
또한 extends를 사용해 과일에 해당하는 타입만 받을수도 잇습니다. fruit는 orange와 apple의 부모입니다.
유니온 또는 제너롤로 받은 여러 객체중 특정 객체의 멤버함수를 호출하고 싶을 떄가 있습니다.
이럴때 유용하게 사용하는게 타입가드입니다.
is string이라는 함수가 있는데 이는 타입가드에서만 사용합니다. split의 경우 number에는 없고 string 에만 있는데, 이를 string 타입이 들어왔을때만 사용하기위해 타입가드를 사용햇습니다.
isString이 타입가드입니다!
string인지 number[]인지 확인하고 알맞은 if문에 타게됩니다~
typeof를 사용해서 타입가드를 할수도있습니다.
열거입니다. 특성이 비슷한 상수를 묶어서 사용할수 잇습니다.
중요한건 상수를 정의할떄 사용한다는 겁니다!!!! 상수는 기본적으로 숫자와 문자열입니다.
any는 모든 타입의 가능성을 시사하지만, union의 경우 지정한 타입중 하나임을 시사합니다.
앞서 union같이 여러 타입을 받을경우 고유의 멤버함수를 가지고 있을수 잇습니다.(예를들면 union으로 허용한 A,B중 A의 객체에는 getid가 있지만, B의 객체에는 getid가 없는경우) 이럴 때 B를 매게변수로 받았는데 getid를 호출하면 에러가 납니다. 그래서 이런경우 type Guard를 사용합니다.
이거 추가 설명다시 보기 .
c++에는 없지만 typescript에 있는 인터페이스, 인터페이스는 변수들이 타입만 지정되어있고, 정의는 되어있지 않습니다. 그래서 클래스에 implements되었다면 정의를 해주어야 사용가능합니다.
그 외에도 덕타이핑 이라는 개념이 있는데, 만약 Drawable이라는인터페이스를 let Drawable이라고 선언할떄 let Drawable = Canvas는 가능합니다. 덕타이핑은 이렇게 implement 되어있지 않은 class도 만약 해당 클래스에 drawing():void가 있다면 Canvas와 똑같이 사용할수 있다 라는 개념입니다.