
1. 클래스에 접근할 수는 있으나 변경할 수 없게 할 때
- readonly 사용하기
type Words = {
[key:string]: string
}
class Dict {
private words: Words
constructor() {
this.words = {}
}
add(word: Word) {
if(this.words[word.term] === undefined) {
this.words[word.term] = word.def;
}
}
def(term:string){
return this.words[term]
}
}
class Word {
constructor(
public readonly term: string,
public readonly def: string
) {}
}
const kimchi = new Word("kimchi", "한국 음식");
kimchi.def = "xxx" // readonly라 에러남 -> JS에 보이지 않음
const dict = new Dict()
dict.add(kimchi);

- static 메서드 : 클래스의 인스턴스가 아닌 클래스 자체에서 호출
type Words = {
[key:string]: string
}
class Dict {
private words: Words
constructor() {
this.words = {}
}
add(word: Word) {
if(this.words[word.term] === undefined) {
this.words[word.term] = word.def;
}
}
def(term:string){
return this.words[term]
}
static hello() {
return "hello"
}
}
class Word {
constructor(
public readonly term: string,
public readonly def: string
) {}
}
const kimchi = new Word("kimchi", "한국 음식");
const dict = new Dict()
dict.add(kimchi);
Dict.hello();

2. 타입과 타입 별칭
- 타입 별칭 : type 키워드 사용하여 정의
- 코드의 가독성을 높이고 타입의 재사용성을 개선
type Player = {
nickName: string,
healthBar: number
}
const min : Player = {
nickName: "min",
healthBar:10
}
type Food = string;
const kimchi:Food = "delicious"

type NickName = string
type HealthBar = number
type Friends = Array<string>
type Player = {
nickName: NickName,
healthBar: HealthBar
}
const min : Player = {
nickName: "min",
healthBar:10
}
type Food = string;
const kimchi:Food = "delicious"
- 제한된 옵션 : 타입에 특정 값을 제한
type Team = "red"|"blue"|"green"
type Health = 1 | 5| 10
type Player = {
nickName: string,
team: Team,
health: Health
}
const min :Player = {
nickName: "min",
team: "red",
health: 5
}

3. 인터페이스
- 한가지 용도만 가지고 있음
- 오브젝트(객체)의 모양을 특정해주는 것 = 객체의 형태를 정의하는 데 사용
type 객체 명= {
변수 명: 타입
}
or
interface 객체 명{
변수 명: 타입
}
type Team = "red"|"blue"|"green"
type Health = 1 | 5| 10
interface Player {
nickName: string,
team: Team,
health: Health
}
const min :Player = {
nickName: "min",
team: "red",
health: 5
}

- 확장
- 다른 인터페이스를 상속받거나 확장할 수 있음
- 합병
- 여러 개의 인터페이스를 정의하고 이를 자동으로 병합할 수 있음
- 같은 이름의 인터페이스가 여러 번 정의되면 TS는 이를 하나로 합침
abstract class User {
constructor(
protected firstName: string,
protected lastName: string
) {}
abstract sayHi(name: string): string;
abstract fullName(): string;
}
class Player extends User {
fullName(): string {
return `${this.firstName} ${this.lastName}`;
}
sayHi(name: string) {
return `Hi, ${name}! My name is ${this.fullName()}`;
}
}

- 추상 클래스가 JS에서는 일반 클래스로 변함

- 인터페이스는 컴파일하면 JS로 바뀌지 않고 사라짐
interface User {
firstName: string,
lastName: string,
sayHi(name: string): string;
fullName(): string;
}
class Player implements User {
}

interface User {
firstName: string;
lastName: string;
sayHi(name: string): string;
fullName(): string;
}
class Player implements User {
constructor(
public firstName: string,
public lastName: string
) {}
}

interface User {
firstName: string;
lastName: string;
sayHi(name: string): string;
fullName(): string;
}
class Player implements User {
constructor(
public firstName: string,
public lastName: string
) {}
fullName(): string {
return `${this.firstName} ${this.lastName}`;
}
sayHi(name: string): string {
return `Hi, ${name}! My name is ${this.fullName()}.`;
}
}

4. 인터페이스와 추상클래스의 차이점
- 인터페이스 (Interface)
- 목적 : 객체의 형태를 정의하는 데 사용 주로 클래스가 특정 형태를 가지도록 강제할 때 사용
- 구성 요소 : 메서드와 속성의 형태만 정의, 실제 구현은 클래스에서 제공
- 확장성 : 다른 인터페이스를 상속받거나 여러 인터페이스를 조합할 수 있음
- 합병 : 동일 이름의 여러 인터페이스가 선언되면, TypeScript는 이들을 자동으로 병합
- 컴파일 : JS로 변환되지 않고 컴파일 단계에서 사라짐
- 다중 상속 : 클래스가 여러 인터페이스를 구현할 수 있음
- 추상 클래스 (Abstract Class)
- 목적 : 공통된 동작을 정의하고, 일부 메서드는 자식 클래스에서 구현하도록 강제
- 구성 요소 : 메서드와 속성 모두를 정의 가능하고, 자식 클래스에서 구현하도록 강제
- 확장성 : 다른 클래스를 상속받거나 자신을 확장할 수 있음
- 컴파일 : JS로 변환되며, 실행 시에 일반 클래스와 같은 방식으로 사용
- 단일 상속 : 클래스는 하나의 추상 클래스를 상속받을 수 있음 JS에서 다중 상속을 지원하지 않음
Share article