노마드코더의 'Typescript로 블록체인 만들기' 강의를 기반으로 정리한 문서입니다. 정말 좋은 무료 강의니까 관심 있으시면 꼭 한 번 보시길 추천합니다!
// In JS
class Player {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
// In TS
class Player {
constructor(
private firstName: string,
private lastName: string,
public nickname: string
) {}
}
const nico = new Player("nico", "las", "니꼬");
console.log(nico);
// Player: { "firstName": "nico", "lastName": "las", "nickname": "니꼬" }
자바스크립트에서는 this.firstName
와 같은 형식으로 this를 사용하여 클래스를 정의했으나, 타입스크립트에서는 아래처럼 private
, public
과 같은 키워드로 class를 정의한다.
class Player {
constructor(
private firstName: string,
private lastName: string,
public nickname: string
) {}
}
const nico = new Player("nico", "las", "니꼬");
console.log(nico.nickname); // "니꼬"
// ERROR! Property 'firstName' is private and only accessible within class 'Player'.
console.log(nico.firstName);
private 키워드로 선언한 속성 혹은 메소드는 해당 class 내부에서만 불러올 수 있고, 인스턴스나 상속 받은 클래스 등 외부에서는 접근이 제한된다.
abstract class User {
constructor(
private firstName: string,
private lastName: string,
public nickname: string
) {}
}
class Player extends User {}
const nico = new Player("nico", "las", "니꼬");
// ERROR! Cannot create an instance of an abstract class.
const wontWork = new User("it", "wont", "work");
추상 클래스(abstract class)란, 다른 클래스가 상속(inherit) 받을 수 있는 클래스를 의미한다. 그러나 추상 클래스를 통해 직접 새로운 인스턴스를 만들 수는 없다.
abstract class User {
constructor(
private firstName: string,
private lastName: string,
protected nickname: string
) {}
abstract getNickName(): void; // this is abstract method.
}
class Player extends User {
getNickName() {
console.log(this.nickname);
}
}
const nico = new Player("nico", "las", "니꼬");
nico.getNickName();
// ERROR! Property 'nickname' is protected and only accessible within class 'User' and its subclasses.
nico.nickname;
추상 메소드(abstract method)란, 추상 클래스를 상속받는 모든 자식 클래스가 반드시 구현해야하는 메소드를 의미한다. 추상 메소드는 추상 클래스 내부에 call signature만 작성하여 선언한다.
private
키워드로 작성된 속성일때는 자식 클래스에서 접근이 제한되지만, 위처럼 protected
키워드로 작성된 속성은 자식 클래스에서도 활용이 가능해지되, 글로벌에서 접근하는 것은 여전히 보호할 수 있다. 어디서든 접근할 수 있게 하면서 오로지 수정만 불가능하게 하고 싶다면 public
과 readonly
를 동시에 사용하면 된다.
class Hello {
static hello() {
return "hello";
}
}
const hello = new Hello();
Hello.hello();
dict.hello(); // Error! Property 'hello' does not exist on type 'Hello'. Did you mean to access the static member 'Hello.hello' instead?
static은 정적 메소드를 정의하는 키워드로서, 타입스크립트만의 기능은 아니다. 클래스의 인스턴스 없이 호출이 가능한 메소드이며, 인스턴스화 되면 호출할 수 없다.
interface는 type과 거의 유사하지만, 좀 더 객체 타입에 특화되었다. type이 객체 이외의 타입도 정의할 수 있기 때문에 다능하나, 일부 interface의 문법이 class와 굉장히 유사한 점이 있기 때문에 특정 상황에서는 interface의 사용이 더 선호되기도 한다.
Differences Between Type Aliases and Interfaces | TypeScript Document
// Using type alias
type Name = {
name: string;
};
type User = Name & {
age: number;
};
// Using interfaces
interface Name {
name: string;
}
interface User extends Name {
age: number;
}
class 문법처럼 extends
키워드를 이용해 타입을 확장시킬 수 있다. 코드 효율로서는 차이가 없을 수는 있어도 문법적으로 class와 비슷하기 때문에 의미가 있다.
interface User {
name: string;
}
interface User {
age: number;
}
const hyeongjin: User = {
name: "hyeongjin",
age: 26,
};
interface는 동일하게 여러 번 호출하면 타입스크립트가 알아서 합쳐준다.
// Using abstract class
abstract class User {
constructor(protected firstName: string, protected lastName: string) {}
abstract getFullName(): string;
abstract sayHi(name: string): string;
}
class Player extends User {
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
sayHi(name: string) {
return `Hello, ${name}. My name is ${this.getFullName()}`;
}
}
// Using interface
interface User {
firstName: string;
lastName: string;
getFullName(): string;
sayHi(name: string): string;
}
class Player implements User {
constructor(public firstName: string, public lastName: string) {}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
sayHi(name: string) {
return `Hello, ${name}. My name is ${this.getFullName()}`;
}
}
예제처럼 interface(혹은 type alias)와 implements
키워드를 사용하면 추상 클래스를 사용하지 않고도 클래스의 타입을 정의할 수 있다. 타입스크립트가 자바스크립트로 컴파일 될 때 추상 클래스는 일반적인 클래스 코드로 변환되지만 interface는 완전히 무시되므로 추상 클래스 대신 interface를 사용하면 성능상의 이점이 있다. 다만, interface로 구현한 클래스의 속성은 반드시 public
키워드만을 사용해야 한다.