자바스크립트는 동적 타입 언어이기 때문에 변수의 타입이 런타임에 의해 결정된다.
타입스크립트는 자바스크립트의 Superset이기 때문에 JS의 모든 기능을 사용할 수 있으며 정적으로 타입을 지정할 수 있는 언어이다.
아래 코드는 JS에서는 실행되지만 TS에서는 에러가 나게 된다.
let v1 = 123;
v1 = 'abc'; // error: type error
이유는 TS에서는 명시적으로 타입을 입력하지 않아도 자동으로 타입을 인식하기 때문이다.
위 코드를 고치면 다음과 같게 된다.
let v1: number | string = 123;
v1 = 'abc'; //succese
변수명 뒤에 콜론을 붙이고 타입을 선언한다. 변수명: 타입
그리고 TS 변수 타입으로는 any, number, boolean, string, number[], Array, 숫자 리터럴과 문자 리터럴까지 다양하게 지정할 수 있다!
함수에는 void타입과 never타입으로 정의할 수 있다.
void : 반환 값이 없는 함수
never : 반환이 안되는 함수 (error나 무한루프 등..)
이외로 반환 값의 타입을 지정해줄 수 있다.
function PrintText(text: string = 'abc', ...rest: string[]):void{
//파라미터 변수 타입 지정과 기본 값 할당 나머지 매개변수 정의, 함수 타입 지정
console.log(text);
}
PrintText(); //abc
객체의 타입은 object 타입이다.
and(&)와 or(|) 연산을 사용해서 교차 타입을 지정할 수 있다.
let v1: (1|3|5) & (3|5|7);
v1 = 3; //success
v1 = 1; //error
type Width = number | string;
let width: Width;
width = 100;
width = '100px';
enum Fruit{
Apple,
Banana, // 자동으로 0 할당
Orange = 5, //원소에 기본 값 할당.
Mango, // 자동적으로 1이 증가된 6이 할당.
}
const v1: Fruit = Fruit.Apple; //열거형 타입 Fruit의 Apple값을 할당
const v2: Fruit.Apple | Fruit.Banana = Fruit.Banana; //값을 타입으로 사용가능
인터페이스는 객체의 타입을 명세할 수 있다!
이외로 원시(primitive) 타입에 메서드를 등록할 때는 인터페이스를 사용한다.
interface String{
getParam(this:string, index: number): string;
}
String.prototype.getParam = getParam;
console.log('asdf, 1234, ok'.getParam(1));
위 코드는 문자열 타입에 getParam 메서드를 추가한다. 문자열의 프로토타입에 getParam을 추가하여 호출할 수 있다.
인터페이스는 객체의 타입을 정의할 때도 사용한다.
interface Person{
name: string;
age: number;
}
const p1: Person = {name: 'mike', age: 23};
const p2: Person = {name: 'mike', age: 'ten'}; //error
function add(x: number, y:number): number;
function add(x: string, y:string): number;
function add(x: number | string, y:number|number): number| string{//...}; // 구현부
객체에서 없어도 되는 속성이면 ?키워드를 붙여서 사용할 수 있다. 선택 속성을 사용하면 객체를 생성할 때 해당 속성을 입력하지 않아도 된다.
interface Person{
name: string;
age?: number;
}
인터페이스 안에서 readonly 키워드를 사용하면 값을 변경할 수 없게 된다.
interface Person{
readonly name: string;
age?: number;
}
두 개의 인터페이스의 역할이 같다면?
interface Person{
name: string;
age: number;
}
interface Product{
name: string;
age: number;
}
이름은 다르지만 내부 구조는 같다.
둘의 집합의 크기가 같기 때문에 서로 할당이 가능하다. 어떤 메소드에서 두 개의 인터페이스의 name이라는 속성을 공유할 수 있을 때를 덕타이핑이라고 한다.
제네릭은 <>기호를 사용하며 이름을 자유롭게 지정할 수 있다. <number>와 같이 제네릭에 타입을 전달할 수 있다.
extends 키워드를 사요하여 제네릭의 타입을 제한할 수 있다
<T extends number|string>