-
[Typescript] ClassLanguage/Typescript 2023. 1. 11. 21:51
๐ ์ฐธ๊ณ : https://poiemaweb.com/typescript-class
๊ธฐ๋ณธ๋ฌธ๋ฒ
ES6 ํด๋์ค๋ ํด๋์ค ๋ด๋ถ์ ๋ฉ์๋๋ง ์ ์ธํ ์ ์๋ค. ์ฆ ๋ฉค๋ฒ๋ณ์(ํ๋กํผํฐ) ์ ์ธ์ ๋ถ๊ฐํ๊ณ , ๋ฉค๋ฒํจ์(๋ฉ์๋)๋ง ์ ์ธ ๊ฐ๋ฅํ๋ค.
๋ฉค๋ฒ๋ณ์์ ์ ์ธ์ ๋ฐ๋์ ์์ฑ์ ๋ด๋ถ์์ ํด๋์ค ํ๋กํผํฐ๋ฅผ ์ ์ธํ๊ณ ์ด๊ธฐํ ํ๋ค.
// person.js class Person { constructor(name) { this.name = name } walk() { console.log(`${this.name} is walking.`) } }
ํ์ง๋ง Typescript ํด๋์ค๋ ํด๋์ค ๋ชธ์ฒด(๋ด๋ถ)์ ํด๋์ค ํ๋กํผํฐ์ ํ์ ์ ์ฌ์ ์ ์ธํ์ฌ์ผ ํ๋ค.
//person.ts class Person { name : string; constructor(name:string) { this.name = name; } walk() { console.log(`${this.name} is walking.`) } } const person = new Person('Lee'); person.walk(); // Lee is walking
์ ๊ทผ์ ํ์
public, private, protected๋ฅผ ์ง์ํ๋ค.
๋ณดํต ๋ค๋ฅธ ๊ฐ์ฒด์งํฅ ์ธ์ด๋ ํด๋์ค์ ํ๋กํผํฐ์ ๋ฉ์๋์ ์ ๊ทผ์ ํ์๋ฅผ ์๋ตํ๋ฉด, ์๋ฌต์ ์ผ๋ก protected ์ธ๋ฐ
typescript๋ public์ด ์๋ฌต์ ์ผ๋ก ์ ์ธ๋๋ค.
๋ฐ๋ฉด, ์์ฑ์ ํ๋ผ๋ฏธํฐ์ ์ ๊ทผ์ ํ์๋ฅผ ์๋ตํ๋ฉด ์์ฑ์ ๋ด๋ถ์์๋ง ์ ํจํ ์ง์ญ๋ณ์๊ฐ ๋์ด ์์ฑ์ ์ธ๋ถ์์ ์ฐธ์กฐ๊ฐ ๋ถ๊ฐ๋ฅํ๋ค.
์ ๊ทผ ์ ํ์๋ฅผ ์ฌ์ฉํ๋ ์ด์ ? ์บก์ํ(encapsulation)!!
- ์ ๊ทผ์ ํ์ ๋ณ ์ ๊ทผ ๊ฐ๋ฅํ ์์น
๐ ์ถ์ฒ : https://velog.io/@mollog/Class-Public-Private-field-MDN-๋ด์ฉ-์ ๋ฆฌ
๊ตฌ๋ถ public protected private ํด๋์ค ๋ด๋ถ O O O ์์ ํด๋์ค ๋ด๋ถ O O X ํด๋์ค ์ธ์คํด์ค O X X - ์์ฑ์ ํ๋ผ๋ฏธํฐ(๋ฉค๋ฒ๋ณ์)์์ ์ ๊ทผ ์ ํ์ ์ ์ธ
์์ฑ์ ํ๋ผ๋ฏธํฐ์ ์ ๊ทผ ์ ํ์๋ฅผ ์ ์ธํ๋ ๊ฒฝ์ฐ, ํด๋น ํ๋ผ๋ฏธํฐ๊ฐ ์๋ฌต์ ์ผ๋ก ํด๋์ค ํ๋กํผํฐ(๋ฉค๋ฒ๋ณ์)๋ก ์ ์ธ๋๊ณ
์์ฑ์ ๋ด๋ถ์์ ๋ณ๋์ ์ด๊ธฐํ(this.parameter)๋ฅผ ํ์ง ์์๋ ์๋ฌต์ ์ผ๋ก ์ด๊ธฐํ๊ฐ ์ํ๋๋ค.
์ด๋, ๋ง์ฝ ์์ฑ์ ํ๋ผ๋ฏธํฐ์ ์ ๊ทผ์ ํ์๊ฐ ์ ์ธ๋์ง ์์ผ๋ฉด,
ํด๋น ํ๋ผ๋ฏธํฐ๋ ์์ฑ์ ๋ด๋ถ์์๋ง ์ ํจํ ์ง์ญ๋ฒ์๊ฐ ๋์ด ์์ฑ์ ์ธ๋ถ์์ ์ฐธ์กฐ๊ฐ ๋ถ๊ฐ๋ฅํ๊ฒ ๋๋ค.
// In Typescript class Player { constructor( private firstName: string, private lastName: string, public nickname: string, score : number ) {} } // Compile to Javascript class Player { constructor(firstName, lastName, nickname, score) { this.firstName = firstName; this.lastName = lastName; this.nickname = nickname; } } const goodPlayer = new Player('๋ช ์', '์ด', '๋น๋', 100); goodPlayer.firstName = "๋ช ์๋ช ์" // error : 'firstName' ์์ฑ์ private์ด๋ฉฐ 'Player' ํด๋์ค ๋ด์์๋ง ์์ธ์ค ํ ์ ์์ต๋๋ค. goodPlayer.nickname = "๋ฐ๋ณด" goodPlayer.score = undefined
- readonly ํค์๋
์ถ์ฒ : http://typescriptstudy.com/ts/article/14-%ED%81%B4%EB%9E%98%EC%8A%A4-class
readonly๊ฐ ์ ์ธ๋ ํด๋์ค ํ๋กํผํฐ๋ ์ ์ธ ์ ๋๋ ์์ฑ์ ๋ด๋ถ์์๋ง ๊ฐ์ ํ ๋นํ ์ ์๋ค. ๊ทธ ์ธ์ ๊ฒฝ์ฐ์๋ ๊ฐ์ ํ ๋นํ ์ ์๊ณ ์ค์ง ์ฝ๊ธฐ๋ง ๊ฐ๋ฅํ๋ค. ์์์ ์ ์ธ ์ ์ฌ์ฉํ๋ค.
class Employee { // ์์ฑ์์์ id ์ง์ ํ ํ ์ฝ๊ธฐ ์ ์ฉ readonly id: number; dept: string; constructor(empId: number) { this.id = empId; } // ์์ฑ ์ ์ธ์ ๊ฐ ์ง์ readonly empType: string = "FTE"; }
- static ํค์๋
์ถ์ฒ : http://typescriptstudy.com/ts/article/14-%ED%81%B4%EB%9E%98%EC%8A%A4-class
ํด๋์ค์ ํ๋กํผํฐ์ ์ ๊ทผํ๊ธฐ ์ํด์๋ ์ธ์คํด์ค๋ฅผ ์์ฑํด์ผ ํ๋ค. ์ฆ 'this.ํ๋กํผํฐ๋ช "์ ํตํค ์ ๊ทผ ๊ฐ๋ฅํ๋ค. ํ์ง๋ง ํด๋์ค ํ๋กํผํฐ์ static ํค์๋๋ฅผ ๋ถ์ด๋ฉด ์ธ์คํด์ค๋ฅผ ์์ฑํ์ง ์๋๋ผ๋ "ํด๋์ค๋ช .ํ๋กํผํฐ๋ช "์ผ๋ก ํด๋น ํ๋กํผํฐ์ ์ ๊ทผ์ด ๊ฐ๋ฅํด์ง๋ค. ์ฆ static ํค์๋๋ ์ ์ ํ๋กํผํฐ๋ฅผ ๋ง๋๋ ํค์๋์ด๋ค.
class Exam { static Cutline: number = 80; scoreCheck(score: number) { if (score >= Exam.Cutline) { console.log("PASS"); } else { console.log("FAIL"); } } } let exam: Exam; exam = new Exam(); console.log("cutline: " + Exam.Cutline); exam.scoreCheck(85);
์ถ์ํด๋์ค
๋ค๋ฅธ ํด๋์ค๊ฐ ์์๋ฐ์ ์ ์๋ ํด๋์ค.
ํ์ง๋ง ์ถ์ ํด๋์ค๋ก๋ ์ง์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค ์ ์๋ค.
abstract class User { constructor( private firstName: string, private lastName: string, public nickname: string ) {} } class Player extends User {} const nico = new User('nico', 'las', '๋๊ผฌ');/ // ์ถ์ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
์ถ์๋ฉ์๋
์ถ์๋ฉ์๋๋ ์ถ์ ํด๋์ค๋ฅผ ์์๋ฐ๋ ํด๋์ค๊ฐ ๊ตฌํ(implement)์ ํด์ผํ๋ ๋ฉ์๋๋ฅผ ์๋ฏธํ๋ค.
์ถ์๋ฉ์๋๋ ์ธ์๋ฅผ ์ ์ํด์๋ ์๋๊ณ , call signatuer๋ง ์ ์ํด์ผ ํ๋ค.
abstract class User { constructor( private firstName: string, private lastName: string, public nickname: string ) {} abstract getNickName(): void; getFullName() { return `${this.firstName} ${this.lastName}`; } } class Player extends User {} //๋น์ถ์ ํด๋์ค 'Player'๋ 'User' ํด๋์ค์์ ์์๋ ์ถ์ ๋ฉค๋ฒ(๋ฉ์๋) ' getNickName'์ ๊ตฌํํ์ง ์์์ต๋๋ค. const nico = new Player('nico', 'las', '๋๊ผฌ');
Interface
๊ฐ์ฒด์ ํ์ ์ ํน์ ํด์ฃผ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
type ํค์๋๋ก๋ ๊ฐ์ฒด์ ํ์ ์ ์ ํ ์ ์์ง๋ง ๊ฐ์ฒด์ ๋ชจ์์ ์ ์ํ๊ธฐ ์ํด ๋ง๋ค์ด์ง inteface๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์๋์ ๋ง๋ ํ์ฉ์ผ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ inteface๋ ๊ฐ์ ์ด๋ฆ์ ๊ฐ์ง ์ธํฐํ์ด์ค๋ฅผ ๋ ์ ์ธ(์ ์ธ ๋ณํฉ)ํ์ฌ ๊ธฐ์กด์ ์ธํฐํ์ด์ค ํ์ ์ ์๋ก์ด ํ์ ์ ์ถ๊ฐํ ์ ์์ง๋ง
typeํค์๋๋ ๊ฐ์ ์ด๋ฆ์ ๊ฐ์ง ํ์ ์ ๋ค์ ์ ์ธํ ์ ์๋ค.
๋ํ ์ธํฐํ์ด์ค๋ ํด๋์ค์ฒ๋ผ ๋ค๋ฅธ ์ธํฐํ์ด์ค๋ฅผ ์์ํ ์ ์๋ค.
์ด์๋ ๋ฐ๋๋ก ์ธํฐํ์ด์ค๋ฅผ ํ์ฉํ๊ธฐ๋ณด๋ค, type alias๋ฅผ ํ์ฉํ๋ ๊ฒ์ด ์ ์ฉํ๋ค๋ ์๊ฒฌ๋ ์๋ค.
1. ํจ์์ type์ ๋ํ๋ด๋๋ฐ ๋ ์ง๊ด์ ์ด๋ค. 2. IDE์์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ๋ ์ ์ง์ํ๋ค. -> ์ธํฐํ์ด์ค๋ call signature๋ฅผ ๋ฐ๋ก ํ์ธํ ์ ์์ง๋ง, type alias๋ ๋ง์ฐ์ค ์ปค์๋ฅผ ๊ฐ์ ธ๋ค ๋๋ฉด ๋ฐ๋ก ํ์ธ์ด ๊ฐ๋ฅํ๋ค. 3. ์์น ์๋ ์ ์ธ ๋ณํฉ์ ๋ง์์ค๋ค.
์ถ์ฒ : https://techblog.woowahan.com/9804/
interface Person { firstName: string; lastName: string; }
// concrete type type Team = "red" | "blue" | "yellow" type Health = 1 | 5 | 10 // we can use interface // interface is only used to make object type // but, type is used in many purposes // Player === Person type Player = { nickname :string team : Team health :Health } interface Person { nickname :string team : Team health :Health } interface User { name: string } // interface is similar to class interface Player extends User { } const nico : Player = { name :"nico" } // we can do this to use type keyword like this type User = { name:string } type Player = User & { } const nico : Player = { name : 'nico' } // // but, When define object shape, inteface is better interface User { name:String } interface User { lastName : string } interface User { health: number } const nico : User = { name:'nico', lastName:'las', health:1 } //also, interface can combine type in same interface params // type extends type PlayerA = { name :string } type PlayerAA = PlayerA & { lastName : string } type PlayerAAA = const playerA : PlayerAA = { name:'nico', lastName :'xxx' } //----------------------// interface PlayerB { name:string } interface PlayerBB extends PlayerB { lastName:string } // or // interface PlayerB { // lastName:string // } const playerB : PlayerB = { name:'nico', lastName : 'yyy' }
์ธํฐํ์ด์ค์ ์ถ์ํด๋์ค์ ์ฐจ์ด
์ถ์ํด๋์ค๋ ๋จ์ํ ํ์คํ๋ ํ๋กํผํฐ์ ๋ฉ์๋๋ฅผ ๊ฐ๋๋กํ๋ ์ฒญ์ฌ์ง ์ญํ ์ ํ๋๋ฐ
์๋ฐ์คํฌ๋ฆฝํธ๋ก ์ปดํ์ผํ๋ฉด ๋จ์ ํด๋์ค๋ก ๋ณํ๋ค.
๋ง์ฝ ์ถ์ํด๋์ค๊ฐ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ก ํด๋์ค๊ฐ ์กด์ฌํ๋ ๊ฒ์ด ์๋ฏธ๊ฐ ์์ ๊ฒฝ์ฐ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ค.
์ธํฐํ์ด์ค๋ ๊ฐ๋ณ๊ธฐ ๋๋ฌธ์ ์ปดํ์ผํ๋ฉด JS๋ก ๋ฐ๋์ง ์๊ณ ์ฌ๋ผ์ง๊ธฐ ๋๋ฌธ์ด๋ค.๋จ, ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ์ ๊ทผ์ ํ์(protected, private)๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ๋ค.
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}` } sayHi (name:string) { return `Hello ${name}. My name is ${this.fullName()}` } } // abstract class can't make instance. // abstract class is just blueprint!! // ๊ทธ๋ ๋ค๋ฉด ์ธํฐํ์ด์ค๋ฅผ ์ธ ๋ ํด๋์ค๊ฐ ํน์ ํํ๋ฅผ ๋ฐ๋ฅด๋๋ก ์ด๋ป๊ฒ ๋ง๋ค ์ ์์๊น? interface User { firstName :string lastName :string sayHi(name:string):string fullName():string } interface Human { health : number } // implements!! // but when implements interface, we can't set properties private, protected class Player implements User, Human { constructor( readonly firstName:string, readonly lastName:string, health : number ){} fullName () { return `${this.firstName} ${this.lastName}` } sayHi (name:string) { return `Hello ${name}. My name is ${this.fullName()}` } } // interface and type both replace abstract class type PlayerA = { firstName:string } interface PlayerB { firstName:string } class User implements PlayerB { constructor ( public firstName:string ){} }
'Language > Typescript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Typescript] Generic (0) 2023.01.11 [Typescript] undefined ๊ด๋ จ error ์ฒ๋ฆฌ ๋ฐฉ๋ฒ (0) 2023.01.06 [Typescript] typescript์ ์ ์ฉ์ฑ, ๊ธฐ๋ณธ์ ์ธ type ์ง์ ๋ฐฉ๋ฒ (0) 2023.01.01 Typescript ๊ธฐ๋ณธ ์ธํ (1) 2022.12.26