컴파일 언어는 런타임에서 에러가 발생하기 전에 컴파일 타임에 미리 에러를 찾아서 고칠 수 있다.
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;
boolean
let isDone: boolean = false;
isDone = true;
console.log(typeof isDone)
👉 실행 결과
true
값을 가진 Boolean
래퍼 객체가 생성되면서 프리미티브 타입인 isNotOk
변수에 할당하려고 하지만 에러가 발생한다.
let isNotOk: boolean = new Boolean(true);
따라서 보통은 리터럴 값으로 프리미티브 타입을 사용한다.
let isOk: Boolean = true;
number
js
와 같이 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;
string
string
형식을 사용한다.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);
👉 실행 결과
symbol
new 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"
null
undefined
--
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");
unknown
any
와 짝으로, 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;
}
never
return
에 사용된다.never
에는 그 어떤 것도 할당할 수 없다.any
조차도 never에게 할당할 수 없다.void
undefined
만 return
할 수 있다.ts
컴파일러가 자동으로 타입을 추론한다.타입이란 해당 변수가 할 수 있는 일을 결정한다.
함수 사용법에 대한 오해를 야기한다.
ts
의 추론에 의지하는 경우 다음과 같은 문제가 발생한다.
이때, nolmplicitAny
옵션을 사용할 수 있다.
🤔
nolmplicitAny
옵션
타입을 명시적으로 지정하지 않은 경우,ts
가 추론 중any
라고 판단하게 되면 컴파일 에러를 발생시켜 명시적으로 지정하도록 유도하는 옵션이다.
또한, 리턴 타입을 지정하지 않아 number
로 추론된 경우 다음과 같은 문제가 발생한다.
이때, strictNullChecks
옵션을 사용할 수 있다.
🤔
strictNullChecks
옵션
모든 타입에 자동으로 포함되어 있는null
과undefined
를 제거해주는 옵션이다.
그렇다면 명시적으로 리턴 타입을 지정해야 할까?
명시적으로 지정한 타입이 일치하지 않아 컴파일 에러가 발생하는데 이때, nolmplicitReturns
옵션을 사용할 수 있다.
🤔
nolmplicitReturns
옵션
함수 내에서 모든 코드가 값을 리턴하지 않으면, 컴파일 에러를 발생시키는 옵션이다.
🤔 나만의 타입 만들기