TypeScript는 JavaScript와 거의 동일한 데이터 타입을 지원한다.
Boolean, Number, String, Array, Tuple, Object, Any 타입이 있다.
Boolean 타입
boolean 값으로 참(true), 거짓(false) 값이다.
let checked: boolean = true;
let isCompleted: boolean = false;
Number 타입
JavaScript와 마찬가지로 TypeScript도 정수와 실수 구분 없이 Number 타입 하나로 표기하며 추가로 bigint를 지원한다.
let number: number = 2;
String 타입
JavaScript처럼 큰따옴표("), 작은따옴표(')를 사용하여 문자열 데이터를 표현하며 백틱(`)을 사용한 템플릿 리터럴을 사용하면 여러 줄에 걸쳐서 문자열을 작성할 수 있다.
let animal: string = "cat";
Array(배열) 타입
JavaScript처럼 값들을 배열로 다룰 수 있으며 두가지 방법으로 배열 타입을 선언할 수 있다.
배열 타입은 기본적으로 하나의 타입만 작성하게 되어 있으며, 타입을 혼용해서 작성하는 것은 불가능하다.
// 배열의 요소들을 나타내는 타입 뒤에 배열을 나타내는 []을 쓰는 방법
let colorList: string[] = ['yellow', 'skyblue', 'violet'];
// 제네릭 배열 타입을 사용, Array를 작성 후에 <>안에 배열의 요소들을 나타내는 타입을 작성
let numberList: Array<number> = [27, 35, 42];
Tuple 타입
튜플 타입을 사용하면 요소의 타입과 개수가 고정된 배열을 표현할 수 있다.
배열의 index마다 타입이 정해져있으므로 정확한 index에 접근할 필요가 있다.
JavaScript에서는 튜플 타입을 명시적으로 선언할 수 없으므로 타입 에러가 더 쉽게 발생하지만 TypeScript에서는 타입 에러를 방지할 수 있다.
let student: [string, number, boolean] = ['jinny', 17, true];
Object 타입
JavaScript처럼 원시 타입이 아닌 타입을 나타낸다. JavaScript에서 객체 타입은 프로퍼티를 가지는 JavaScript 값을 말하며 typeof 연산자를 사용했을 때 Object를 반환하는 모든 타입을 의미한다.
TypeScript에서 object 타입은 모든 객체를 수용하는 타입이며 객체의 프로퍼티 타입들이 any로 지정되므로 어떤 프로퍼티라도 추가할 수 있지만 타입 안정성을 보장하지 않는다.
그러므로 객체의 프로퍼티 타입들을 각각 명시해 주는 것이 좋으며 key-value에 구체적인 타입까지도 지정할 수 있다.
let obj: object = {};
let student: {name: string, age: number} = {
name: "minji",
age: 24
}
Any 타입
any타입은 어떠한 데이터나 서트파티 라이브러리에서 들오는 값인 경우에 개발자가 알지 못하는 타입일 수 있는데 타입 검사를 하지 않고자 할 때 사용할 수 있다.
any 타입을 사용하게 되면, 변수에 값을 재할당하는 경우에 타입을 명시한 변수가 아니므로 타입에 상관없이 재할당할 수 있으며 실제 할당된 값이 가지지 않는 메서드 및 프로퍼티로 접근해도 에러가 나지 않는다. 실제로 할당된 값이 가지지 않는 메서드 및 프로퍼티의 반환되는 값은 undefined이다.
any 타입은 타입의 일부만 알고 전체를 알지 못할 때 유용하게 사용할 수 있다.
let question: any = 'why?';
// any 타입이므로 index의 1번째 요소가 number타입이지만 string타입으로 재할당할 수 있다.
let list: any[] = ['string', 2, true]
list[1] = 'hello'
TypeScript에서도 JavaScript처럼 named function, arrow function으로 만들 수 있다.
TypeScript에서 함수를 표현할 때는 타입 추론 기능을 활용하지 않는다면 매개변수의 타입과 반환 타입을 명시해줘야 한다. 만약에 함수에 리턴값이 없다면, void를 사용하여 작성할 수 있다.
TypeScript는 JavaScript와 달리 매개변수의 개수에 맞춰 전달인자를 전달해야 하며 매개변수의 개수가 맞지 않다면 에러가 난다. 매개변수의 값을 전달하지 않을 경우를 대비하여 JavaScript에서의 default parameter처럼 할당된 매개변수의 값을 정해놓을 수도 있다.
선택적 매개변수를 원한다면 매개변수의 이름 끝에 ?를 붙여서 해결할 수 있다.
function add(a : number, b: number):number {
return a + b;
}
let answer = (): void => {
console.log("Yes");
}
let student = (name: string, subject: string): string => {
return `${name} : ${subject}`
}
// 정상적으로 작동
student('hani', 'Computer Science');
// 너무 많은 매개변수를 보내면 에러 발생
student('hani', 'Computer Science', 'hello');
TypeScript는 연산자를 이용해 타입을 정할 수 있다. JavaScript에서 ||(OR)연산자, &&(AND)연산자를 이용하여 만들 수 있다. | 연산자를 이용한 유니온(Union)타입과, & 연산자를 이용한 인터섹션(Intersection)타입이 있다.
유니온(Union) 타입
유니온 타입은 둘 이상의 타입이 합쳐서 만들어진 새로운 타입이다. 자바스크립트의 ||(OR)연산자와 같다. number | string은 숫자 또는 문자열 타입을 의미한다. 유니온 타입은 다양한 값을 처리해야 하는 경우 유용하다. any타입을 사용하면 타입을 추론할 수 없어서 자동완성 기능을 사용하기 어렵지만 유니온 타입을 사용할 경우 타입을 추론할 수 있으며 코드의 가독성도 높일 수 있다.
// value 값이 문자열, 숫자, 불리언 타입 중 하나의 값을 가질 수 있다고 명시적으로 표시하여 코드를 쉽게 이해할 수 있다.
let value: string | number | boolean;
// 유니온 타입인 값이 있을 경우에는 유니온에 있는 모든 타입에 공통인 멤버들에만 접근할 수 있다 => 공통되고 보장된 프로퍼티만 제공하므로 name에만 접근
interface Student {
name: string;
subject: string;
}
interface Person {
name: string;
age: number;
}
function newStudent(someone: Student | Person) {
console.log(someone.name)
}
위의 예시는 공통 프로퍼티에만 접근 가능하므로 나머지 프로퍼티에도 접근하고 싶다면 타입 가드를 사용해야 한다.
// TypeScript에서 in 연산자를 이용해 해당 프로퍼티가 객체 내에 존재하는지 여부를 검사한다.
function newStudent(someone: Student | Person) {
if('subject' in someone) {
console.log(someone.subject)
}
}
인터섹션(Intersection) 타입
인터섹션 타입은 & 연산자를 사용하여 둘 이상의 타입을 결합하여 새로운 타입을 만든다.
새로운 교집합을 만들어내므로 전달인자를 전달할 때 모든 프로퍼티를 전부 보내줘야 한다.
// User는 Student와 Person에 정의된 속성 모두를 받는다.
interface Student {
name: string;
subject: string;
}
interface Person {
name: string;
age: number;
}
type User = Student & Person;