하나의 언어이자, 타입이라는 개념을 적용시킨 javaScript 에러 발생을 줄일 수 있음
typed superset of js
complies to plain js
브라우저나 노드에서 실행 가능한 js로 compile 됨
complie 혹은 transpile 이라고 표현
자바스크립트 - interpreted language
타입스크립트 - compiled language
n | Compiled | InterPreted |
---|---|---|
컴파일 | 필요O | 필요X |
컴파일러 | 필요O | 필요X |
컴파일하는 시점 | 필요O =>컴파일타임 | 필요X |
diff | 컴파일된 결과물 실행 | 코드 자체를 실행 |
diff | 컴파일된 결과물을 실행하는 시점 존재 | 코드를 실행하는 시점 존재 = 런타임 |
Requirement: node.js, browser, typescript compiler
typescript compiler
npm 사용
npm i typescript
-g: global option
how to complie :global
> tsc test.ts
문제없이 컴파일시 test.js 파일 생성
or
tsc --init를 통해 tsconfig.json를 생성하고
tsc 입력시 해당 설정값에 맞춰 compile 됨
or
tsc -w
-w : watch option
파일이 수정될때 마다 자동으로 컴파일 가능
node_modules/typescript/bin/tsc
or
node_modules/.bin/tsc
하지만 두개다 명령어가 길기 때문에
npm를 사용해서 npx tsc를 사용한다
npx tsc --init // make tsconfig.json
npx tsc //compile
or
package.json 파일의 script를 부분을 수정해서 npm build를 사용함
변수에 타입을 지정해주는것
TS = Static Types
개발 중간에 타입을 체크
JS = Dynamic Types
개발할때는 모름, 런타임시 알 수 있음
let a: number; //a에 대하여 number type 지정
a = "Mark"; //Error
a = 39;
function hello(b: number) {
}
hello('mark'); //Error
// JavaScript
function add(n1, n2) {
if (typeof n1 !== 'number' || typeof n2 !== 'number') {
throw new Error('Incorrect input!');
}
return n1 + n2;
}
const result = add(39, 28);
------------------------------------------------------------
// TypeScript
function add(n1: number, n2: number) {
return n1 + n2;
}
const result = add(39, 28);
JS의 기본 자료형 포함 (superset)
ecmascript 6가지 와 Array
boolean, number, string, null, undefined, symbol + Array(object)
추가 타입
any, void, never, unknown
enum
tuple(object) (array와 비슷)
Primitive type (JS에서 온것)
오브젝트와 레퍼런스 형태가 아닌 실제 값을 저장하는 type
내장 함수를 사용 가능한것은 JS처리 방식 덕분
리터럴 값으로 primitive type의 서브 타입을 나타낼 수 있음
boolean number string null undefined symbol
wrapper object화 가능
example)
new Boolean(false); //typeof new Boolean(false) : object
new String('world'); ////typeof new String('world') : object
new Number(42); ////typeof new String(42) : object
let isDone: boolean = false;
isDone = true;
console.log(typeof isDone);
let isOk: Boolean = true;
let isNotok: boolean = new Boolean(true); //error
//모든 숫자는 부동소수점 값
//10진수
let decimal: number = 6;
//16진수 사용가능
let hex: number = 0xf00d;
//2진수
let binary: number = 0b1010;
//8진수
let octal: number = 0o744;
let notANumber: number = NaN;
let underscoreNum: number = 1_000_000;
//JS와 같이 "나 ' 사용
let myName: string = "Mark";
myName = 'Anna';
//Template String 미사용시
//let sentence: string = "Hello, my name is " + fullName + ".\n\n" +
// "I'll be " + (age + 1) + " years old next month.";
//Template String 사용시 (백틱)
let fullName: string = 'Mark Lee';
let age: number = 38;
let sentence: string = `Hello, my name is ${ fullName }.
I'll be ${ age + 1 } years old next month.`;
console.log(sentence)
//Hello, my name is Mark Lee.
//I'll be 39 years old next month.
프리미티브 타입의 값을 담아서 사용
고유하고 수정 불가능한 값으로 만듬
문자열로는 접근이 불가하고, 심볼을 얻어서 접근하도록 제어하는데 씀
//ECMAScript 2015의 Symbol
//new Symbol 사용 불가
//함수로 사용시 Symbol
//타입으로 사용시 symbol
console.log(Symbol('foo') === Symbol('foo')); // false
const sym = Symbol();
const obj = {
[sym]: "value",
};
obj["sym"] //Error
console.log(obj[sym]) //value
let Myname: string = null; //error
let u: undefined = null; //error
let v: void = null; //error
let v: void = undefined; //okay
let union: string | null = null;
//string null 둘다
union = "Mark"
// create by object literal
const person1 = {name: 'Mark', age: 39};
// person1 is not "object" type.
// person1 is "{name: string, age: number}" type.
// create by Object.create
const person2 = Object.create({name: 'Mark', age: 39});
//const person2 = Object.create(39); //error
let obj: object = {}; //No
obj = {name: 'Mark'};
obj = [{name: 'Mark'}]; //array
obj = 39; // Error
obj = 'Mark'; // Error
obj = true; // Error
obj = 100n; // Error
obj = Symbol(); // Error
obj = null; // Error
obj = undefined; // Error
//primitive type을 막고싶을때
declare function create(o: object | null): void;
create({ prop: 0 });
create(null);
create(42); // Error
create("string"); // Error
create(false); // Error
create(undefined); // Error
// Object.create
Object.create(0); // Error
//선언 방식
let list: number[] = [1, 2, 3];
let list: (number | string)[] = [1, 2, 3, "4"];
let list: Array<number> = [1, 2, 3];
// 앞뒤로 각각의 타입
let x: [string, number];
x = ["hello", 39];
//순서 타입 길이 모두 맞아야함
x = [10, "Mark"] //error
x[2] = "world"; //error
const person: [string, number] = ["Mark", 39];
const [first, second] = person;
//first = string
//second = number
const [first, second, third] = person; //error
function returnAny(message: any): any {
console.log(message);
}
const any1 = returnAny("리턴은 아무거나");
any1.toString(); //okay
----------------------------------------
let looselyTyped: any = {};
const d = looselyTyped.a.b.c.d;
----------------------------------------
function leakingAny(obj: any) {
const a = obj.num;
const b = a + 1; // b: any
return b;
}
const c = leakingAny({num: 0}) //c : any
c.indexOf("0"); //okay
--------------leak를 막는 방식--------------
function leakingAny(obj: any) {
const a: number = obj.num;
const b = a + 1; // b: number
return b;
}
const c = leakingAny({num: 0}) //c : number
c.indexOf("0"); // error
declare const maybe: unknown;
const aNumber: number = maybe;
//unknown은 넘버에 바로 할당이 불가
//타입가드
if (maybe === true) { //maybe : unknown
const aBoolean: Boolean = maybe; //maybe : boolean
const aString: string = maybe: //error
}
//타입오브 타입가드
if (typeof maybe === "string") {
const aString: string = maybe; //maybe: string
const aBoolean: Boolean = maybe; //error
}
//만약 maybe가 any 였다면 바로 할당도 가능하고, if문도 사용할 필요가 없음
//하지만 unknown를 사용하면, 타입 시스템이 도와주기 때문에 runtime error 실수가 줄어듬
let const a: string = 'hello';
if (typeof a !== 'string') {
a; //a: never ( string - string = nerver)
}
----------------------------------------
declare const a: string | number;
if (typeof a !== 'string') {
a; //a: number ( string + number - string = number)
function returnViud(message: string):void {
console.log(message);
return;
}
const r = returnViud("리턴이 없음"); //r : void