
컴파일 언어는 런타임에서 에러가 발생하기 전에 컴파일 타임에 미리 에러를 찾아서 고칠 수 있다.
| Compiled | Interpreted |
|---|---|
| 컴파일 필요 ⭕ | 컴파일 필요 ❌ |
| 컴파일러 필요 ⭕ | 컴파일러 필요 ❌ |
| 컴파일하는 시점 ⭕(👉 컴파일 타임) | 컴파일하는 시점 ❌ |
| 컴파일된 결과물을 실행 | 코드 자체를 실행 |
| 컴파일된 결과물을 실행하는 시점 | 코드를 실행하는 시점 ⭕(👉 런타임) |
타입스크립트는 노드나 브라우저 같은 런타임 환경에서 바로 읽어서 사용할 수 없다.
따라서 컴파일러를 통해 플레인 자바스크립트로 변경해주어야 한다.

node.js 설치(ref: https://velog.io/@jytrack/패스트-캠퍼스-MGS-3기-4월-25일JS)
컴파일러를 사용한 간단한 예제이다.
프로젝트(폴더)를 생성하고 해당 프로젝트에서 다음 명령어를 입력한다.
npm init -y
npm i typescript
tsconfig.json 파일을 생성하기 위해 다음 명령어를 입력한다.
npx tsc --init
프로젝트에 다음과 같은 파일이 생성되었다.

test.ts 파일을 생성한 후,
// test.ts
console.log('Hello')
다음 명령어로 컴파일한다.
npx tsc
js 파일이 생겼다!

🤔
npx tsc
프로젝트 안에 존재하는 모든 타입스크립트 파일을 전부 컴파일하려면npx tsc를 입력하면 된다.
이때, 어떤 식으로 컴파일 할 것인지 설정 파일을 넣어주어야 한다. 설정 파일을 자동으로 생성해주는 디폴트 명령어이다.
이 명령어를 입력하면 파일(tsconfig.json)이 생성된다.npm tsc --init🤔 파일을 수정했을 때 자동으로 컴파일이 되도록 하는 법
매번 명령어를 입력해 수동으로 컴파일 할 필요 없이 다음 명령어를 통해 자동으로 컴파일 하도록 설정할 수 있다.npx tsc -w
보통은 npx tsc로 바로 실행하지 않고, 현재 프로젝트의 어떤 스크립트가 돌아갈 수 있는지 등록한다. package.json의 script를 다음처럼 수정한다.
"scripts": {
"build": "tsc"
},
이제 다음 명령어를 사용해 tsc를 실행할 수 있다!
npm run build
🤔 VSCode에서 버전 선택
npm init -y // 실제 런타임에 필요하지 않으므로 보통은 -D 플래그를 붙인다. npm i typescript -D
다음처럼 :을 사용해 특정한 변수나 객체에 타입을 지정하는 것을 'Type Annotation'이라고 한다.
let a: string;
// 가능
a = "Mark"
// 불가능
a = 39
let a: number;
// 불가능
a = "Mark"
// 가능
a = 39
function hello(b: number) {
}
// 가능
hello(39)
// 불가능
hello('Mark')
js에서는 throw를 사용해 런타임에서 에러를 체크하는 반면, ts에서는 이러한 과정이 필요없다. 개발 시에 에러를 체크할 수 있다.

ECMAScript 표준에 따른 기본 자료형 6가지
프로그래밍을 도울 몇가지 타입이 더 제공
let name = 'mark';
name.toString();true;
'hello';
3.14;
null;
undefined;booleanlet isDone: boolean = false;
isDone = true;
console.log(typeof isDone)
👉 실행 결과

true 값을 가진 Boolean 래퍼 객체가 생성되면서 프리미티브 타입인 isNotOk 변수에 할당하려고 하지만 에러가 발생한다.
let isNotOk: boolean = new Boolean(true);
따라서 보통은 리터럴 값으로 프리미티브 타입을 사용한다.
let isOk: Boolean = true;
numberjs와 같이 ts의 모든 숫자는 부동 소수점 값이다._를 이용한 표기법// 십진수
let decimal: number = 6;
// 16진수
let hex: number = 0xf00d;
// 이진수
let binary: number = 0b1010;
// 8진수
let octal: number = 0o744;
//NaN
let notANumber: number = NaN;
// _를 이용한 표기법
let underscoreNum: number = 1_000_000;
stringstring 형식을 사용한다.let myName: string = "Mark";
myName = 'Anna';
${expr}와 같은 형태로 사용한다.let fullName: string = 'Mark Lee';
let age: number = 39;
let sentence: string = `Hello, My name is ${ fullName }.
I'll be ${age + 1} years old next month.`;
console.log(sentence);
👉 실행 결과

symbolnew Symbol로 사용할 수 없다.Symbol을 함수로 사용해서 symbol 타입을 만들어낼 수 있다.console.log(Symbol("foo") === Symbol("foo")); // false
❓ 같은 함수이고, 같은 인자를 넣었지만 false가 나왔다.
그렇다면 symbol은 어디에 사용될까?
const sym = Symbol();
const obj = {
[sym]: "value",
};
// 접근 불가능
obj["sym"]
// 접근 가능
obj[sym]
null & undefinednull 및 undefined이라는 타입을 가진다.let u: undefined = undefined;
let n: null = null;
number에 null 또는 undefined를 할당할 수 있다는 의미이다.--strictNullChecks를 사용하면, null과 undefined는 void나 자기 자신들에게만 할당할 수 있다. (보통은 이 옵션을 켜둔다.)null과 undefined를 할당할 수 있게 하려면, union type을 이용해야 한다.// 불가능
let v: void = void;
let v: void = null;
// 가능
let v: void = undefined;
// union type
let union: string | null = null;
union = "Mark"
nullundefined--
object

js에서는 객체이다.Array<타입>, 타입[]// 보통 위에 있는 방식을 더 많이 사용한다.
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];
let list: (number | string)[] = [1, 2, 3, "4"];
let x: [string, number];
// 가능
x = ["hello", 24];
// 불가능, 순서가 같아야 한다.
x = [24, "Mark"];
// 불가능, 길이가 같아야 한다.
x[3] = "world";
// 가능
const person: [string, number] = ["Mark", 24];
// 불가능, 길이가 같아야 하므로 세 번째 요소 X
const [first, second, third] = person;
어떤 타입이어도 상관없는 타입이다.
최대한 쓰지 않는 것이 타입 시스템을 안전하게 유지할 수 있다.
컴파일 옵션 중 any를 써야 하는데 쓰지 않으면 오류를 뱉도록 하는 옵션이 있다. (nolmplicitAny)
하지만 any를 사용할 수 밖에 없는 부분이 있다. 다음과 같은 경우, 로그만 찍고 있으므로 숫자나 문자라는 규정이 필요없다.
function returnAny(message: any): any {
console.log(message);
}
any는 계속해서 개체를 통해 전파된다.
let looselyTyped: any = [];
const d = looselyTyped.a.b.c.d;
// a, b, c 타입이 모두 any
function leakingAny(obj: any) {
const a = obj.num;
const b = a + 1;
return b;
}
const c = leakingAny({ num: 0 });
c.indexOf("0");
// a, b, c 타입이 모두 number로 누수를 막음
function leakingAny(obj: any) {
const a: number = obj.num;
const b = a + 1;
return b;
}
const c = leakingAny({ num: 0 });
c.indexOf("0");
unknownany와 짝으로, any보다 타입-세이프하다.any처럼 아무거나 할당할 수 있다.// 타입가드, maybe에 'true'라는 타입을 지정한다.
if (maybe === true) {
// 'true'이므로 boolean은 가능
const aBoolean: boolean = maybe;
// string은 불가능
const aString: string = maybe;
}
// 타입가드, maybe에 'string'이라는 타입을 지정한다.
if (typeof maybe === 'string') {
// 'string'이므로 string은 가능
const aString: string = maybe;
// boolean은 불가능
const aBoolean: boolean = maybe;
}
neverreturn에 사용된다.never에는 그 어떤 것도 할당할 수 없다.any 조차도 never에게 할당할 수 없다.

voidundefined만 return 할 수 있다.
ts 컴파일러가 자동으로 타입을 추론한다.
타입이란 해당 변수가 할 수 있는 일을 결정한다.

함수 사용법에 대한 오해를 야기한다.

ts의 추론에 의지하는 경우 다음과 같은 문제가 발생한다.
이때, nolmplicitAny 옵션을 사용할 수 있다.

🤔
nolmplicitAny옵션
타입을 명시적으로 지정하지 않은 경우,ts가 추론 중any라고 판단하게 되면 컴파일 에러를 발생시켜 명시적으로 지정하도록 유도하는 옵션이다.
또한, 리턴 타입을 지정하지 않아 number로 추론된 경우 다음과 같은 문제가 발생한다.
이때, strictNullChecks 옵션을 사용할 수 있다.

🤔
strictNullChecks옵션
모든 타입에 자동으로 포함되어 있는null과undefined를 제거해주는 옵션이다.
그렇다면 명시적으로 리턴 타입을 지정해야 할까?
명시적으로 지정한 타입이 일치하지 않아 컴파일 에러가 발생하는데 이때, nolmplicitReturns 옵션을 사용할 수 있다.

🤔
nolmplicitReturns옵션
함수 내에서 모든 코드가 값을 리턴하지 않으면, 컴파일 에러를 발생시키는 옵션이다.
🤔 나만의 타입 만들기