
public이지만 수정이 불가능하도록 하고 싶으면?
type Words = {
[key:string]: string
}
class Dictionary{
private words: Words
constructor(){
this.words = {}
}
add(word: Word){
if(this.words[word.term] === undefined){
this.words[word.term] = word.def;
}
}
// term을 사용해 word를 찾는 메소드
def(term: string){
return this.words[term]
}
static hello(){
return "hello";
}
}
class Word {
constructor(
// readonly 기능을 사용
public readonly term: string,
public readonly def : string
){}
}
const kimchi = new Word("kimchi", "한국의 음식")
const dict = new Dictionary()
dict.add(kimchi);
dict.def("kimchi")
Dict.hello() // static메소드
// 타입을 쓰는 첫번째 방법
type Player = {
// Player타입을 정의하는 방법
nickname: string,
healthBar: number
}
const hong: Player = {
nickname: "hong"
healthBar: 10
}
// 타입을 쓰는 두번째 방법
type Food = string;
const kimchi: Food = "delicious"
// 타입을 쓰는 세번째 방법 ( alias )
type Nickname = string
type HealthBar = number
type Friends = Array<string> // string의 배열
type Player = {
nickname: string,
healthBar: number
}
const hong: Player = {
nickname: Nickname
healthBar: HealthBar
}
키워드 type을 이용해 타입스크립트에서 만들고 싶은 무수히 많은 종류의 타입을 설명하면 된다
타입을 지정된 옵션으로만 제한하는 방법
type Team = "red" | "blue" | "yellow"
// 이렇게 concrete타입의 특정값들을 사용할 수 있다
type Health = 1 | 5 | 10
type Player = {
nickname: string,
team: Team, // team이 일반적인 string이 아닌 특정 string이 되도록 하는 방법
health: Health
}
const nico: Player = {
nickname: "hong",
team: "yellow"
health: 10
}
type Team = "red" | "blue" | "yellow"
type Health = 1 | 5 | 10
interface Player {
// 인터페이스는 한가지 특징을 가짐 : object의 모양을 특정해주기 위함
nickname: string,
team: Team,
health: Health
}
const nico: Player = {
nickname: "hong",
team: "yellow"
health: 10
}
1) type Player = {}
2) interface Player{}
- 차이점 : type키워드는 interface키워드에 비해 좀 더 활용할 수 있는게 많다
- interface Hello = string 이건 불가능하다!!!
interface는 class와 비슷하다
//interface 사용
interface User {
name: string
// readonly name: string 이것도 가능
}
interface Player extends User{
}
const hong : Player = {
name: "hong"
}
// type 사용
type User = {
name: string
}
type Player = User & {
}
const hong : Player = {
name: "hong"
}
interface는 property들을 축적시킬 수 있다
interface User{
name: string
}
interface User{
lastName: string
}
interface User{
health: number
}
const hong: User = {
name: "hong",
lastName: "yun",
health: 5
}
// interface를 3번 각각 만들어도 타입스크립트가 알아서 하나로 합쳐준다
// type으로는 할 수 없다
// 추상클래스는 이걸 상속받는 다른 클래스가 가질 property와 메소드를 지정하도록 해준다
// 만약 User클래스를 상속한다면, sayHi, fullName을 구현해야하고, firstName, lastName을 갖게 된다
// 상속받는 클래스가 어떻게 동작해야할지 일러주기 위해서 추상클래스를 사용한다
abstract class User{
constructor(
protected firstName: string,
protected lastName: string
){}
abstract sayHi(name: string): string
abstract fullName(): string
}
class Player extends User{
fullName(){
return `${this.firstName} ${this.lastName}`
// protected는 추상클래스롤부터 상속받은 클래스들이 property에 접근하도록 해준다
// private를 쓰면 firstName, lastName을 Player가 접근할 수 없다
}
sayHi(name: string){
return `Hello ${name}. My name is ${this.fullName()}`
}
}
interface User{
firstName: string,
lastName: string,
sayHi(name: string): string,
fullName(): string
}
interface Human{
health: number
}
class Player implements User, Human{ // 여러개를 한번에 상속받을 수 있다
// interface를 상속할때는 private,protected를 사용하지 못한다
// public이어야만 한다
constructor(
public firstName: string,
public lastName: string,
public health: number
){}
fullName(){
return `${this.firstName} ${this.lastName}`
}
sayHi(name: string){
return `Hello ${name}. My name is ${this.fullName()}`
}
}
인터페이스를 타입으로 지정할 수도 있다
function makeUser(user: User){
return "hi"
}
makeUser({ // argument에 인터페이스를 씀으로써 object모양을 지정해줄 수 있다
firstName: "hong",
lastName: "yun",
fullName: () => "xx",
sayHi: (name) => "string"
}) // ()안에는 user를 넣어줘야한다 즉, 인터페이스를 타입으로 쓸 수 있다
// new User를 할 필요가 없이 interface의 내용물만 넣어주면 된다
클래스를 타입으로 쓸 수 있고, 인터페이스를 타입으로 쓸 수 있다
인터페이스를 사용해 클래스에 특정 메소드나 property를 상속하도록 강제하는 방법을 배움
(인터페이스는 원하는 메소드와 property를 클래스가 가지도록 강제할 수 있게 해준다)
인터페이스는 자바스크립트로 컴파일 되지 않고 사라진다
추상클래스와 비슷한 보호를 제공하지만, 인터페이스는 js파일에서 보이지 않는다
추상클래스를 쓰면 js에서는 일반 클래스로 바뀐다
첫번째, 타입을 쓰고 싶으면 type키워드를 사용하면 된다
type의 옵션은 object모양을 설명하는 것, 타입 alias를 만드는 것, 타입을 특정된 값으로 만드는 것
인터페이스와 비교할 내용은 object모양을 알려줄 때
// ts에게 object모양을 알려주는 것이 목표
// 타입
type PlayerA = {
name: string
}
const playerA : PlayerA = {
name: "hong"
}
// 인터페이스
interface PlayerB{
name: string
}
const playerB : PlayerB = {
name: "hong"
}
둘의 목표는 같지만 타입과 인터페이스로 할 수 있는 것들이 조금 다르다
type PlayerA = {
name: string
}
type PlayerAA = PlayerA & {
lastName: string
}
// type PlayerAA = {} 이렇게 추가하는 건 안된다
const playerA : PlayerAA = {
name: "hong",
lastName: "xxx"
}
// 인터페이스
interface PlayerB{
name: string
}
interface PlayerBB extends PlayerB{
lastName: string
}
// interface에서는 이름이 중복되어도 가능하다
interface PlayerBB {
health: number
}
const playerB : PlayerBB = {
name: "hong",
lastName: "xxx"
}
type PlayerA = {
firstName: string
}
interface PlayerB{
firstName: string
}
class User implements PlayerA{
constructor(
public firstName: string
){}
}
// 둘다 가능하다
class User implements PlayerB{
constructor(
public firstName: string
){}
}