
TypeScript의 타입 별칭(Type Aliases)타입 별칭(Type Aliases)은 타입의 새로운 이름을 만드는 것
새로운 이름으로 기존의 타입을 참조하는 것을 의미
타입 별칭을 이용하여 타입의 새로운 이름을 만들 때 키워드 type을 사용하여 작성
type MyString = string;
let str1: string = 'hello!';
// string 타입처럼 사용할 수 있습니다.
let str2: MyString = 'hello world!';
원래 string이라는 타입이 존재하고 있어, myString이라는 새로운 이름을 부여.
myString과 string은 동일한 의미를 갖게 됨.이런 방식으로 타입 별칭을 사용하면 코드를 더 간결하고 가독성 좋게 만들 수 있다.
또한 복잡한 타입을 간략하게 표현하고, 타입 정의를 재사용하는 등 가독성을 높일 수 있다.
type Person = {
id: number;
name: string;
email: string;
}
//Commentary 인터페이스에서 Person 타입을 참조하고 있습니다.
interface Commentary {
id: number;
content: string;
user: Person;
}
//객체에서 Commentary 인터페이스를 참조하고 있습니다.
let comment1: Commentary = {
id: 1,
content: "뭐예요?",
user: {
id: 1,
name: "김코딩",
email: "kimcoding@codestates.com",
},
}
//Commentary 인터페이스 내부에 content 프로퍼티가 존재하기 때문에
//content 프로퍼티를 작성하지 않으면 컴파일 에러가 납니다.
let kimcoding: Commentary = {
id: 1,
user: {
id: 1,
name: "김코딩",
email: "kimcoding@codestates.com",
},
};
//Person 타입 내부에 isDeveloper 프로퍼티가 존재하지 않기 때문에
//isDeveloper 프로퍼티를 작성할 시 컴파일 에러가 납니다.
let kimcoding: Commentary = {
id: 1,
content: "뭐예요?",
user: {
id: 1,
name: "김코딩",
email: "kimcoding@codestates.com",
isDeveloper: true,
},
};
인터페이스나 다른 변수를 정의할 때 타입 별칭으로 정의한 타입을 참조하게 됨으로써 코드를 더 간결하고 가독성 좋게 만들 수 있다.
타입 별칭으로 만들어진 타입을 참조할 시에는 인터페이스와 마찬가지로 내부에 정의된 프로퍼티를 전부 참조해야만 한다.
또한 타입 별칭으로 만들어진 타입 내부에 정의된 프로퍼티 외에 다른 프로퍼티를 더 작성하게 되면 그 또한 컴파일 에러가 난다.
타입 별칭 또한 인터페이스와 같은 특징이 있기 때문에, 인터페이스의 역할을 타입 별칭이 수행할 수도 있다.
그러나 인터페이스와 타입 별칭에는 미묘한 차이점이 있다.
type Person = {
name: string;
age: number;
}
interface User {
name: string;
age: number;
}
let kimcoding: Person = {
name: '김코딩',
age: 30,
}
let coding: User = {
name: '김코딩',
age: 30,
}
작성하는 동안 정의한 타입이나 인터페이스 내부에 어떤 프로퍼티가 들어가 있는지 기억이 나지 않을 경우가 있다.
kimcoding이 참조하고 있는 Person 타입과, coding이 참조하고 있는 User 인터페이스에 각기 마우스를 올려놓아 보았다.

kimcoding 객체가 참조하고 있는 Person 내부에 어떤 프로퍼티들이 정의되어 있는지 보이지만, coding 객체가 참조하고 있는 User에 내부에 어떤 프로퍼티들이 정의되어 있는지 보이지 않는다.따라서 타입 별칭으로 정의한 타입으로 작성할 시에는 조금 더 편하게 코드를 작성할 수 있게 된다.
// 이러한 차이점이 있다.
type Person = {
name: string;
age: number;
}
interface User {
name: string;
age: number;
}
//에러가 발생합니다.
type Students extends Person {
className: string;
}
//정상적으로 동작합니다.
interface Students extends User {
className: string;
}
//정상적으로 동작합니다.
interface Students extends Person {
className: string;
}
TypeScript의 타입 추론(Type Inference)TypeScript는 정적타입을 지원하는 프로그래밍 언어
(Type Inference)의 기본타입 추론(Type Inference)은 변수나 함수의 타입을 선언하지 않아도 TypeScript가 자동으로 유추하는 기능.let isNumber = 123;isNumber를 선언123을 할당isNumber의 타입을 자동으로 숫자(Number)로 추론(Best common type)"최적 공통 타입"을 계산.let x = [0, 1, null];x 타입을 추론하려면 각 배열 요소의 타입을 고려해야 한다. number와 null 있다.(Contextual Typing)function add(a, b) {
return a + b;
}add 함수는 두 개의 매개변수를 받아 더한 값을 반환.a와 b의 타입을 자동으로 추론했다.a와 b가 모두 숫자(Number) 타입이라면, add 함수의 반환 값도 숫자(Number) 타입으로 추론된다.TypeScript의 클래스(Class)JavaScript와 TypeScript 모두 객체 지향 프로그래밍을 지원하며 클래스(class)를 사용하여 객체를 생성할 수 있다.
그러나 두 언어의 클래스는 몇 가지 차이점이 있다.
JavaScript에서의 클래스(Class)JavaScript에서 클래스를 사용하면 객체를 생성하고 객체의 속성과 메서드를 정의할 수 있다.
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`안녕하세요, 제 이름은 ${this.name}이고, ${this.age}살 입니다.`);
}
}
Person 클래스는 name과 age 속성을 가지고 greet() 메서드를 정의.const person = new Person('Alice', 30);
person.greet(); // "안녕하세요, 제 이름은 Alice이고, 30살 입니다."TypeScript에서의 클래스(Class)TypeScript의 클래스는 JavaScript의 클래스와 비슷하지만 몇 가지 추가된 기능이 있다.
TypeScript에서는 클래스의 속성과 메서드에 대한 타입을 명시할 수 있다.
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet(): void {
console.log(`안녕하세요, 제 이름은 ${this.name}이고, ${this.age}살 입니다.`);
}
}
name 속성과 age 속성은 문자열과 숫자 타입으로 정의.
약간의 차이점은 TypeScript에서 클래스를 정의할 때, constructor를 이용하여 초기화하는 멤버들은 전부 상단에서 정의를 해줘야 한다는 것.
또한 contructor 내 인자로 받을 때도 정확히 타입을 명시해 줘야 한다.
const person = new Person('Alice', 30);
person.greet(); // "안녕하세요, 제 이름은 Alice이고, 30살 입니다."(Inheritance)TypeScript의 클래스(class)는 인터페이스(interface)와 마찬가지로 기존에 존재하던 클래스를 상속받아 확장하여 새로운 클래스를 만들 수 있다.
이때도 extends 키워드를 사용하여 상속할 수 있다.
class Animal {
move(distanceInMeters: number): void {
console.log(`${distanceInMeters}m 이동했습니다.`);
}
}
class Dog extends Animal {
speak(): void {
console.log("멍멍!");
}
}
const dog = new Dog();
dog.move(10);
dog.speak();
Animal이라는 클래스를 Dog라는 클래스가 상속받고 있다.
Dog 클래스는 Animal 클래스로부터 프로퍼티와 메서드를 상속받으며, Dog 클래스는 파생 클래스라고도 불리며, 하위클래스(subclasses)라고도 불린다.
여기서 Animal 클래스는 기초 클래스, 상위클래스(superclasses)라고 불린다.
public, private 키워드기본적으로 클래스 내에 선언된 멤버는 외부로 공개되는 것이 디폴트 값.
public 키워드를 사용class Person {
public name: string;
public age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet(): void {
console.log(`안녕하세요, 제 이름은 ${this.name}이고, ${this.age}살 입니다.`);
}
}
// 혹은 외부에 드러내지 않을 멤버가 있다면 private 키워드로 명시해 주면 된다.
class Person {
public name: string;
private age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet(): void {
console.log(`안녕하세요, 제 이름은 ${this.name}이고, ${this.age}살 입니다.`);
}
}
readonly 키워드readonly키워드를 사용하여 프로퍼티를 읽기 전용으로 만들 수 있다.
읽기 전용 프로퍼티들은 선언 또는 생성자에서 초기화해야 한다.
class Mydog {
readonly name: string;
constructor(theName: string) {
this.name = theName;
}
}
let spooky = new Mydog("스푸키");
spooky.name = "멋진 스푸키"; // 에러
name이 readonly로 명시되어 있기 때문에, 값을 변경할 수 없다.
이런 식으로 변경되면 안 될 값을 readonly로 명시하여 보호할 수 있다.