https://typescript-kr.github.io/
Typescript is Javascript's flavor or variant.
자바스크립트는 처음에 브라우저를 위한 스크립트 언어로 만들어졌다.
웹 브라우저 개발자들은 JS 사용량이 늘어나면서 실행 엔진(동적 컴파일)을 최적화시키고 최적화된 것을 이용해 할 수 있는 일(API 추가)을 확장하여 JS를 더 인기있게 만들었다.
하지만 Javascript에는 문제들이 존재한다.
"" == 0 //true
1 < x < 3 //x가 어떤 값이던 true
const obj = { width: 10, height: 15 };
const area = obj.width * obj.h; //NaN
대부분의 프로그래밍 언어는 이런 종료의 오류가 발생하면 오류를 보여주고 일부는 코드가 실행되기 전인 컴파일 중에 오류를 표출한다.
프로그램을 실행시키지 않으면서 코드의 오류를 검출하는 것을 정적 검사 라고 한다.
어떤 것이 오류인지와 어떤 것이 연산되는 값에 기인하지 않음을 정하는 것이 정적 타입 검사.
정적타입 vs 동적타입
정적타입
컴파일 시 변수의 타입이 결정되는 언어, 따라서 변수에 들어갈 값의 타입을 명시해주어야 한다. 타입이 맞지 않는 값이 있을 경우 컴파일 에러가 발생!
동적타입
런타임 시 변수의 타입이 결정되는 언어, 타입없이 변수를 선언하여 값을 지정할 수 있다. 단점으로는 런타임에 예상치 못한 타입 에러가 발생할 수 있음!
정적 타입 검사자인 TypeScript는 프로그램을 실행시키기 전에 값의 종류를 기반으로 프로그램의 오류를 찾는다.
// @errors: 2551
const obj = { width: 10, height: 15 };
const area = obj.width * obj.h;
구문(syntax)
타입스크립트는 자바스크립트의 구문이 허용되는 자바스크립트의 상위 집합 언어이다. 구문은 프로그램을 만들기 위해 코드를 작성하는 방법을 의미한다.
타입(types)
타입스크립트는 다른 종류의 값들을 사용할 수 있는 방법이 추가된, 타입이 있는 상위 집합이다. obj.h
의 오류는 구문 오류가 아닌 타입 오류이다.
타입스크립트의 타입 검사자는 일반적인 오류를 최대한 많이 검출하면서 올바른 프로그램을 만들 수 있게 설계되어있다.
런타임 특성(runtime behavior)
타입스크립트는 자바스크립트의 런타임 특성을 가진 프로그래밍 언어이다.
런타임과 컴파일타임
프로그램을 생성하기 위해 개발자는 소스코드를 작성하고 코드는 컴파일을 통해 기계어 코드로 변환되어 실행 가능한 프로그램이 되며 이러한 과정을 컴파일타임이라고 한다.
컴파일과정을 마친 프로그램은 사용자에 의해 실행되어 지며, 프로그램이 실행되고 있는 동안을 런타임이라고 부른다.
타입스크립트는 자바스크립트 코드의 런타임 특성을 절대 변화시키지 않는다!
즉 타입스크립트가 코드에 타입 오류가 있음을 알아도 자바스크립트 코드를 타입스크립트로 이동시키는 것은 같은 방식으로 실행시킬 것을 보장한다.
두 언어 간에 쉽게 전환할 수 있도록 하기 위한 타입스크립트의 기본적인 약속.
삭제된 타입(Erased Tyeps)
타입스크립트의 컴파일러가 코드 검사를 마치면 타입을 삭제해서 결과적으로 컴파일 된 코드 를 만든다. 즉 코드가 컴파일 되면 결과로 나온 js코드에는 타입 정보가 없다.
타입 정보가 없는 것은 타입스크립트가 추론한 타입에 따라 프로그램의 특성을 변화시키지 않는다는 의미로, 컴파일 도중에는 타입에러가 발생할 수 있지만 프로그램이 실행될 때와는 관련이 없다.
타입스크립트는 추가 런타임 라이브러리가 없다. 자바스크립트와 같은 표준 라이브러리를 사용한다.
Typescript는 Javascript위에 레이어로서 자리잡고 있으며 Jaavascript의 기능들을 제공하면서 그 위에 자체 레이어를 추가한다. 그 레이어가 Typescript의 타입 시스템
javascript의 리터럴타입
Boolean, null, undefined, Number, BigInt, String, Symbol, Object
Typescript의 타입 검사기는 사용자가 생각한 일과 Javascript가 시렞로 하는 일 사이의 불일치를 강조할 수 있다.
Typescript는 변수를 생성하면서 동시에 특정 값에 할당하는 경우 그 값을 해당 변수의 타입으로 사용한다.
Javascript가 동작하는 방식을 이해함으로써 TS는 JS를 받아들이면서 타입을 가지는 타입 시스템을 구축할 수 있다.
Javascript 는 다양한 디자인 패턴을 가능하게 하는 동적 언어이다.
Typescript는 타입이 무엇인지 명시 가능한 Javascript 언어의 확장을 지원.
name: string과 id: numver 를 포함하는 추론 타입을 가진 객체
const user = {
name: "Silver",
id: 0
}
이 객체의 형태를 명시적으로 나타내기 위해서 interface
로 선언하고
변수 선언 뒤에 : TypeName
의 구문을 사용해 Javascript 객체가 새로운 interface 형태를 따르고 있음을 선언할 수 있다.
interface User {
name: string;
id: number
}
const user: User = {
name: "Silver",
id: 0
}
Javascript는 클래스와 객체 지향 프로그래밍을 지원하기 때문데 Typescript 또한 동일하며 인터페이스는 클래스로 선언할 수 있다.
interface User {
name: string;
id: number;
}
class UserAccount {
name: string;
id: number;
constructor(name: string, id: string) {
this.name = name;
this.id = id;
}
}
const user: User = new UserAccount("Dong", 1);
객체지향에서의 Interface
클래스에서 구현부가 빠진 설계도. 어떠한 객체가 어떤 프로퍼티 혹은 메소드를 가지늕지 설계하고 선언하는 역할. 추상메서드와 상수를 멤버로 가진다. 실질적인 구현은 이를 구현한다고 선언하는 클래스가 한다. 클래스는 인터페이스에 있는 프로퍼티 및 메소드를 모두 가지고 구현해야한다.
Javascript에서 사용할 수 있는 리터럴 타입이 이미 있다. Typescript 는 몇 가지를 추가해 목록을 확장한다.
any
(무엇이든 허용)
unknown
(이 타입을 사용하는 사람이 타입이 무엇인지 확인)
never
(이 타입은 발생될 수 없음)
void
(undefined를 리턴하거나 리턴값이 없는 함수)
객체들을 조합하여 더 크고 복잡한 객체를 만드는 방법과 유사하게 TS에 타입으로 이를 수행하는 도구가 있다.
타입이 여러 타입 중 하나일 수 있음을 선언하는 방법
type MyBool = true | false;
function getLength(obj : string | string[]) {
return obj.length;
}
타입에 변수를 제공하는 방법, <타입으로 사용되는 식별자>
제네릭이 있는 배열은 배열안의 값을 설명할 수 있다.
type StringArray = Array<string>;
type ObjectWithNameArray = Array<{name: string}>;
interface Backpack<Type> {
add: (obj: Tyepe) => void;
}
declare const backpack: Backpack<string>;
backpack.add(23) //error, backpack 변수가 string이므로 number를 전달할 수 없음
객체지향에서의 제네릭
제네릭은 어떠한 클래스 혹은 함수에서 사용할 타입을 그 함수나 클래스를 사용할 때 결정하는 프로그래밍 기법
타입스크립트의 핵심 원칙 중 하나는 타입 검사가 값이 있는 형태에 집중한다는 것.
= 덕 타이핑(duck typing) = 구조적 타이핑
interface Point {
x: number;
y: number;
}
function printPoint (p: Point) {
console.log(`${p.x}, ${p.y}`);
}
const point = { x: 12, y: 26 };
printPoint(point);
const rect = { x:33, y:3, width: 30, height: 80};
printPoint(rect);
여기서 point
변수는 Point
타입으로 선언된 적이 없지만 타입스크립트의 타입 검사해서 둘 다 같은 형태기 때문에 패스한다.
형태 일치는 일치시킬 객체의 필드의 하위 집합만 필요하다.
Typescript는 정적 타이핑을 사용하는 언어에 익숙한 프로그래머들에게 인기있는 선택이다.
Javascript의 런타임 동작을 이해하기 위해 우선적으로 타입을 제외한 Javascript의 일부분을 배우는 것이 좋다. Typescript는 Javascript와 동일한 런타임을 사용하믐로 특정한 런타임 동작을 구현하려는 리소스는 항상 타입스크립트 프로그램에 똑같이 잘 적용되다는 점을 기억하는 것은 매우 중요하다.
자바스크립트의 런타임
런타임(runtime)이란 프로그래밍 언어가 구동되는 환경을 의미
Node.js나 크롬 등의 여러 브라우저들은 자바스크립트가 구동되는 환경이기 때문에 node.js나 브라우저가 자바스크립트의 런타임
자바스크립트는 싱글스레드, 논-블로킹 언어 : 하나의 힙 영역과 하나의 콜 스택(함수가 실행되는 순서를 기억하고 있다)을 가지며 그 의미는 한번에 한가지 일밖에 못한다는 의미이다.
참고링크
js에서 함수는 어디에나 있을 수 있고 미리 정의된 class나 struct에 속하지 않고 자유롭게 전달할 수 있다. 자유로운 함수는 프로그램을 자바스크립트로 작성하는 모델로 선호된다.
싱글턴과 같은 정적 클래스 같은 특정 구조는 필요없다.
싱글턴
인스턴스를 하나만 만들어 사용하기 위한 패턴
유일한 단일 객체를 반환할 수 있도록 정적 메소드를 지원해야 한다.
타입스크립트는 인터페이스, 상속, 정적(static) 메서드 구현과 같은 일반적인 패턴을 지원한다.
static
변수 선언 시 static 키워드를 붙이면 자바의 경우 메모리 할당을 한번만 하게 되어 메모리 사용에 이점이 있다.
C#또는 자바에서 런타임 타입과 해당 컴파일 타입 선언 사이의 일대일 대응 관계는 중요하다.
타입스크립트에서 타입은 공통의 무언가를 공유하는 값의 집합으로 생각하는 것이 좋다. 타입은 집합에 불과하기 때문에 특정한 값은 동시에 여러 집합에 속할 수 없다.
객체는 정확히 단일 타입이 아니다.
예를 들어 인터페이스를 만족하는 객체를 생성할 때 둘 사이의 선언적인 관계가 없더라도 해당 인터페이스가 예상되는 곳에 해당 객체를 사용할 수 있다.
타입스크립트의 타입 시스템은 구조적이고 구체화되지 않았다. 타입은 런타임에 어떤 형태로도 존재하지 않는다.
빈타입 (Empty Types)
class Empty {}
function fn(arg: Empty) {}
fn({k: 10});
타입스크립트는 주어진 인수가 유효한 Empty인지를 확인하여 fn의 호출이 유효한지를 검사한다. {k:10}과 Empty의 구조를 확인하여 유효서을 검사한다. Empty에 프로퍼티가 없으므로 유효한 호출이다.
동일한 타입(Identical Types)
class Car {
drive() {}
}
class Golfer {
drive() {}
}
let w: Car = new Golfer();
두 클래스의 구조가 동일하기 때문에 에러가 발생하지 않는다.
객체지향은 제네릭을 포함하여 어떤 값의 유형이라도 다룰 수 있음에 익숙하다.
자바스크립트에는 typeof
와 instanceof
와 같은 제한된 원시요소가 있지만 이러한 연산자는 타입이 지워진 코드의 출력에 존재하므로 여전히 작동함을 알아야 한다. typeof(new Car()) 는 Car가 아닌 object다.
자바스크립트는 프로그래밍 커뮤티티에 도입된지 20년이 지난 지금, 가장 널리 퍼진 cross-platform 언어 중 하나다.
프로그래머들이 작성하는 가장 흔한 오류는 타입오류 이다. TypeScript의 목표는 JavaScript 프로그램의 정적 타입 검사자이다. 즉, 코드가 실행되기 전에 실행하고(정적), 프로그램 타입이 정확한지 확인하는 도구(타입 검사)이다.
자바스크립트의 핵심 개념을 전부 소개하지는 않는다.
핸드북은 언어 명세를 대체하기 위함이 아니다.
프로그램이 유용하려면 숫자, 문자열, 구조체, 불리언과 같은 간단한 데이터 단위가 필요하다. 타입스크립트는 자바스크립트와 거의 비슷하며 열거 타입을 사용할 수 있다.
let isDone: boolean = true;
참/거짓 (true/false)
자바스크립트처럼 타입스크립트의 모든숫자는 부동 소수 값.
TypeScript는 16진수, 10진수 리터럴에 더불어 2진수, 8진수 리터럴도 지원한다.
let decimal: number = 6;
let hex: number = 0xf00d;
텍스트 데이터 타입을 string으로 표현한다. 큰타옴표(") 나 작은따옴표(')를 문자열 데이터를 감싸는데 사용한다.
let color: string = "blue";
배열 타입을 두가지 방법으로 쓸 수 있다.
타입 뒤에 []를 쓰는 방법
let list: number[] = [1,2,3];
제네릭 배열 타입을 쓰는 것 Array<elemType>
let list: Array<number> = [1,2,3];
튜플 타입을 사용하면 요소의 타입과 개수가 고정된 배열을 표현할 수 있다.
단 요소들의 타입이 모두 같을 필요는 없다.
//튜플 타입으로 선언
let x: [string,number];
x = ["hello", 10]; //성공
x = [10, "hello"]; //에러
console.log(x[1].substring(1)); //에러 number에는 substring이 없음
x[3] = 에러"world"; // 프로퍼티 3이 없음
console.log(x[5].toString()); //에러 프로퍼티 5가 없음
Jvascript의 표준 자료형 집합과 사용하면 도움이 될만한 데이터 형은 enum
enum은 값의 집합에 더 나은 이름을 붙여줄 수 있다.
enum Color {Red = 1, Green, Blue};
let c: Color = Color.Green;
let colorName: string = Color[2];
console.log(colorName); //Green
기본적으로 enum은 0부터 시작하여 멤버들의 번호를 메기며 수동으로 설정하여 위처럼 값을 변경할 수 있다.
유요한 기능 중 하나는 매겨진 값을 이용해 enum의 멤버의 이름을 알아낼 수 있다.