Interface
Table of contents
- λ νμ΄ν (Duck Typing)
- μΈν°νμ΄μ€μ νλ‘νΌν° νμ μ μ
- μ νμ νλ‘νΌν° (Optional Properties)
- μ½κΈ°μ μ© νλ‘νΌν° (Readonly Properties)
- λ³μ μΈν°νμ΄μ€
- μμΈκ°λ₯ νμ (Indexable Types)
- ν¨μ νλΌλ―Έν°μ μΈν°νμ΄μ€
- ν¨μ νμ (Function Types)
- νμ΄λΈλ¦¬λ νμ (Hybrid Types)
- ν΄λμ€ νμ (Class Types)
- μΈν°νμ΄μ€ νμ₯
- μμ½
- reference
interface
ν€μλλ₯Ό μ¬μ©ν΄ κ°μ΄ νΉμ ν νν(shape)λ₯Ό κ°λλ‘ μ μ½ν μ μλ€. μΈν°νμ΄μ€μ μ μΈλ νλ‘νΌν° λλ λ©μλμ ꡬνμ κ°μ νμ¬ μΌκ΄μ±μ μ μ§ν μ μλλ‘ νλ κ²μ΄λ€. μ΄λ μ¬λ¬κ°μ§ νμ
μ κ°λ νλ‘νΌν°λ‘ μ΄λ£¨μ΄μ§ μλ‘μ΄ νμ
μ μ μνλ κ²κ³Ό μ μ¬νλ€.
λ νμ΄ν (Duck Typing)
TypeScriptλ κ°μ²΄κ° νΉμ μΈν°νμ΄μ€μμ μ μν(λͺ μνλ) νλ‘νΌν°λ λ©μλλ₯Ό κ°μ§κ³ μλ€λ©΄ ν΄λΉ κ°μ²΄κ° κ·Έ μΈν°νμ΄μ€λ₯Ό ꡬνν κ²μΌλ‘ μΈμ νλ€. μΈν°νμ΄μ€λ₯Ό νμ©νλ©΄ λ νμ΄νμ ν λ λ©μλλ₯Ό κ²μ¬νμ§ μκ³ λ λ°νμ μλ¬λ₯Ό λ§μ μ μλ€.
λ νμ΄ν(duck typing) / ꡬ쑰μ νμ΄ν(structural typing)
λμ νμ΄νμ ν μ’ λ₯λ‘, κ°μ²΄μ λ³μ λ° λ©μλμ μ§ν©μ΄ κ°μ²΄μ νμ μ κ²°μ νλ κ²μ λ§νλ€. ν΄λμ€ μμμ΄λ μΈν°νμ΄μ€ ꡬνμΌλ‘ νμ μ ꡬλΆνλ λμ , λ νμ΄νμ κ°μ²΄κ° μ΄λ€ νμ μ κ±Έλ§μ λ³μμ λ©μλλ₯Ό μ§λλ©΄ κ°μ²΄λ₯Ό ν΄λΉ νμ μ μνλ κ²μΌλ‘ κ°μ£Όνλ€.
strictνκ² νμ΄νμ νκ³ μΆλ€λ©΄ implements
ν€μλλ₯Ό μ¬μ©νμ¬ λͺ
μμ μΌλ‘ μ μΈν΄μ£Όλ κ²λ μ’μ λ°©λ²μ΄λ€.
μΈν°νμ΄μ€μ νλ‘νΌν° νμ μ μ
// μΈν°νμ΄μ€ μ μinterface InterfaceName {key: string; // νλ‘νΌν° νμ μ μ}
μ νμ νλ‘νΌν° (Optional Properties)
νλ‘νΌν° μ΄λ¦ λμ ?
λ₯Ό λΆμ¬ Optional Propertiesλ‘ μ μΈ ν μ μλ€.
μ νμ μΌλ‘ μ¬μ© κ°λ₯ν νλ‘νΌν°λ₯Ό μμ±νλ©΄μ μΈν°νμ΄μ€μ μνμ§ μλ νλ‘νΌν°μ μ¬μ©μ λ°©μ§ ν μ μλ€.
interface User {name: string;age?: number; // optional property}
μ νμ μ¬μ© κ°λ₯ν νλ‘νΌν°λ₯Ό μ½κ² νμ ν μ μμ΄ μ½λμ κ°λ μ±μ΄ μ’μμ§λ€.
μ½κΈ°μ μ© νλ‘νΌν° (Readonly Properties)
νλ‘νΌν° μ΄λ¦ μμ readonly
ν€μλλ‘ κ°μ²΄κ° μ²μ μμ±λ λλ§ μμ κ°λ₯νκ²λ 리λμ¨λ¦¬ νλ‘νΌν°λ‘ μ μΈ ν μ μλ€.
μμ±νλ©΄μ ν λΉ ν κ°μ μ¬ν λΉμ΄ λΆκ°λ₯ν΄ μ§λ€. Type assertionμΌλ‘ μ€λ²λΌμ΄λνλ κ²μ κ°λ₯νλ€.
interface User {readonly name: string;age: number;}
λ³μ μΈν°νμ΄μ€
μΈν°νμ΄μ€λ₯Ό νμ μΌλ‘ μ μΈν λ³μλ ν΄λΉ μΈν°νμ΄μ€λ₯Ό μ€μνμ¬μΌ νλ€.
// μΈν°νμ΄μ€μ μ μinterface Todo {id: number;content: string;completed: boolean;}// λ³μ todoμ νμ μΌλ‘ Todo μΈν°νμ΄μ€λ₯Ό μ μΈνμλ€.let todo: Todo;// λ³μ todoλ Todo μΈν°νμ΄μ€λ₯Ό μ€μνμ¬μΌ νλ€.todo = { id: 1, content: 'typescript', completed: false };
μμΈκ°λ₯ νμ (Indexable Types)
Indexable typeμ μΈλ±μ€ μκ·Έλμ²(index signature)λ₯Ό μ¬μ©ν΄ λμ μ΄λ©΄μ μμΈ κ°λ₯ν(indexable) κ°μ²΄μ νμ
μ μ μν μ μκ³ , λ¬Έμμ΄ λλ μ«μλ§ μ¬μ© κ°λ₯νλ€. readonly
ν€μλλ‘ μμΈ μμ μ½κΈ° μ μ©μΌλ‘ μ μΈν μ μλ€.
μΈλ±μ€ μκ·Έλμ² (Index signature)
μΈλ±μλΈ νμ μ μ μνκΈ° μν΄ μμΈμ μ κ·Όν λ μ¬μ©νλ κΈ°νΈμΈ λκ΄νΈ
[]
λ₯Ό μ΄μ©ν΄ Indexableνκ² λ§λ€μ΄ μ€λ€.
[INDEXER_NAME: INDEXER_TYPE]: RETURN_TYPE
typescriptinterface Indexable {[key: string]: any; // index signature}
κ΄νΈ νκΈ°λ²μΌλ‘ λμ μΈ ν€ κ°μ μ¬μ©νμ¬ μ κ·Όνλ €λ κ²½μ°
TypeScriptμμ κ΄νΈ νκΈ°λ²μΌλ‘ λμ μΈ ν€ κ°μ μ¬μ©νμ¬ μ κ·Όνλ €λ κ²½μ°, μ΄λ€ νμ
μ νλ‘νΌν°μ μ κ·Όνλ μ§ μ μ μκΈ° λλ¬Έμ λ¦¬ν΄ κ°μ μ묡μ μΌλ‘ any
νμ
μΌλ‘ λ³ννλ©΄μ μλ¬λ₯Ό λ°μμν¨λ€. μ΄λ κ² μ½λμ μ€ν μμ μμλ§ μ μ μλ μ΄λ¦μ λμ μμ±μ κ°λ νμ
μ νμν λ μ¬μ© ν μ μλ€.
μμΈμ νμ μΌλ‘ λ¬Έμμ΄ μμΈκ³Ό μ«μ μμΈμ΄ λͺ¨λ μ‘΄μ¬νλ κ²½μ°
μμΈμ νμ μΌλ‘ λ¬Έμμ΄ μμΈκ³Ό μ«μ μμΈμ΄ λͺ¨λ μ‘΄μ¬νλ κ²½μ° μ«μλ‘ μμΈ λ κ°μ νμ μ λ¬Έμμ΄λ‘ μμΈ λ κ° νμ μ μλΈνμ μ΄μ΄μΌ νλ€.
// Bλ Aμ μλΈνμ μ΄μ΄μΌ νλ€.interface Mixed <A, B> {[stringIndex: string]: A;[numberIndex: number]: B;}
μ΄λ¬ν μ μ½μ΄ μ‘΄μ¬νλ μ΄μ λ μλ°μ€ν¬λ¦½νΈ μμΈμ λμ λ°©μ λλ¬Έμ΄λ€. μλ°μ€ν¬λ¦½νΈ μ½λμμ κ°μ²΄μ μμΈμ μ κ·Όν λ, λ΄λΆμ μΌλ‘λ μμΈμ toString()
λ©μλλ₯Ό νΈμΆν΄ λ¬Έμμ΄λ‘ λ³νλ κ°μ μμΈμΌλ‘ μ¬μ©νλ€.
μΈλ±μλΈ νμ μ μ¬μ© μ
λ§μ½ μμΈ κ°λ₯ νμ μ΄ μμ΄
T
νμ μ μμλ₯Ό κ°λArray
μΈν°νμ΄μ€λ₯Ό μμ±νλ€λ©΄ λλ΅ μλμ κ°μ μμΌλ‘ λͺ¨λ μμΈμ λν νμ μ μΌμΌμ΄ μ μν΄μΌ ν κ²μ΄λ€.typescriptinterface Array<T> {length: number;0?: T;1?: T;/* ... */Number.MAX_SAFE_INTEGER?: T;/* λ©μλ μ μ */}μΈλ±μ€ νμ μ μ΄μ©νλ©΄ μ μ½λλ₯Ό λ€μμ²λΌ κ°κ²°νκ² λ체ν μ μλ€.
typescriptinterface Array<T> {length: number;[index: number]?: T;/* λ©μλ μ μ */}
ν¨μ νλΌλ―Έν°μ μΈν°νμ΄μ€
μΈν°νμ΄μ€λ₯Ό μ¬μ©νμ¬ ν¨μ νλΌλ―Έν°μ νμ μ μ μΈ ν μ μλ€. ν΄λΉ ν¨μμλ ν¨μ νλΌλ―Έν°μ νμ μΌλ‘ μ§μ ν μΈν°νμ΄μ€λ₯Ό μ€μνλ μΈμλ₯Ό μ λ¬νμ¬μΌ νλ€. μ΄λ ν¨μμ κ°μ²΄λ₯Ό μ λ¬ν λ 볡μ‘ν 맀κ°λ³μ 체ν¬κ° νμμμ΄μ λ§€μ° μ μ©νλ€.
// μΈν°νμ΄μ€μ μ μinterface Todo {id: number;content: string;completed: boolean;}let todos: Todo[] = [];// νλΌλ―Έν° todoμ νμ μΌλ‘ Todo μΈν°νμ΄μ€λ₯Ό μ μΈνμλ€.function addTodo(todo: Todo) {todos = [...todos, todo];}// νλΌλ―Έν° todoλ Todo μΈν°νμ΄μ€λ₯Ό μ€μνμ¬μΌ νλ€.const newTodo: Todo = { id: 1, content: 'typescript', completed: false };addTodo(newTodo);console.log(todos)// [ { id: 1, content: 'typescript', completed: false } ]
ν¨μ νμ (Function Types)
μΈν°νμ΄μ€λ ν¨μμ νμ
μΌλ‘ μ¬μ©ν μ μλ€. ν¨μ μΈν°νμ΄μ€λ₯Ό ꡬννλ ν¨μ λ μΈν°νμ΄μ€λ₯Ό μ€μνμ¬μΌ νλ€.
νΈμΆ μκ·Έλμ²(call signature)λ‘ ν¨μμ μΈν°νμ΄μ€μ νμ
μ΄ μ μΈλ νλΌλ―Έν° 리μ€νΈμ λ¦¬ν΄ νμ
μ μ μνλ€.
νΈμΆ μκ·Έλμ²(Call signature)
μλ³μ μμ΄, λ°μμΌν μΈμμ νμ κ³Ό, λ¦¬ν΄ νμ λ§μ νκΈ°νλ©΄ λλ€.
(PARAMETER1: PARAM1_TYPE, PARAMETER2: PARAM2_TYPE, ...): RETURN_TYPE
typescriptinterface Callable {(key: string): any // call signature}
// ν¨μ μΈν°νμ΄μ€μ μ μinterface SquareFunc {(num: number): number; // call signature}// ν¨μ μΈν νμ΄μ€λ₯Ό ꡬννλ ν¨μλ μΈν°νμ΄μ€λ₯Ό μ€μνμ¬μΌ νλ€.const squareFunc: SquareFunc = function (num: number) {return num * num;};console.log(squareFunc(10)); // 100
ν¨μ μ μμ μΈν°νμ΄μ€μμμ 맀κ°λ³μ μ΄λ¦μ κΌ κ°μ νμλ μκ³ λ§€κ°λ³μμ νμ μμλ§ λ§λλ€λ©΄ μλ¬λ λ°μνμ§ μλλ€.
νμ΄λΈλ¦¬λ νμ (Hybrid Types)
μ½ μκ·Έλμ²μ νλ‘νΌν° νμ μ μλ₯Ό λμμ κ°λ μΈν°νμ΄μ€λ₯Ό νμ΄λΈλ¦¬λ νμ (hybrid type)μ΄λΌ λΆλ₯Έλ€.
νΈμΆ κ°λ₯(callable) νλ©΄μ λμμ μΆκ°μ μΌλ‘ μ¬λ¬ μμ±μ κ°λ κ°μ²΄κ° μ‘΄μ¬ν μ μκ³ , μ΄λ° κ°μ²΄μ νμ μ νννκΈ° μν΄ μ½ μκ·Έλμ³μ νλ‘νΌν° νμ μ μλ₯Ό λμμ μ¬μ© ν μ μλ€.
interface Counter {(start: number): string;interval: number;reset(): void;}function getCounter(): Counter {let counter = <Counter>function (start: number) { };counter.interval = 123;counter.reset = function () { };return counter;}let c = getCounter();c(10);c.reset();c.interval = 5.0;
μμ Counter
νμ
μ κ°μ ν¨μλ‘μ νΈμΆ ν μ μκ³ , λ°λΌμ νΈμΆ μκ·Έλμ³λ₯Ό κ°λλ€. μ΄ μΈν°νμ΄μ€λ μΆκ°μ μΌλ‘ interval
κ³Ό reset
μ΄λΌλ μμ±μ κ°μ§λ€. λ°λΌμ μΈν°νμ΄μ€λ ν΄λΉ μμ±μ νμ
μ 보 λν ν¬ν¨νλ€.
ν΄λμ€ νμ (Class Types)
ν΄λμ€ μ μΈλ¬Έμ implements
λ€μ μΈν°νμ΄μ€λ₯Ό μ¬μ©νλ©΄ ν΄λΉ ν΄λμ€λ μ§μ λ μΈν°νμ΄μ€λ₯Ό λ°λμ ꡬννμ¬μΌ νλ€.
μΈν°νμ΄μ€λ νλ‘νΌν°μ λ©μλλ₯Ό κ°μ§ μ μλ€λ μ μμ ν΄λμ€μ μ μ¬νλ μ§μ μΈμ€ν΄μ€λ₯Ό μμ±ν μλ μλ€.
// μΈν°νμ΄μ€μ μ μinterface ITodo {id: number;content: string;completed: boolean;}// Todo ν΄λμ€λ ITodo μΈν°νμ΄μ€λ₯Ό ꡬννμ¬μΌ νλ€.class Todo implements ITodo {constructor (public id: number,public content: string,public completed: boolean) { }}const todo = new Todo(1, 'Typescript', false);console.log(todo);
μΈν°νμ΄μ€μ μΆμ λ©μλ
μΈν°νμ΄μ€λ νλ‘νΌν°λΏλ§ μλλΌ λ©μλλ ν¬ν¨ν μ μλ€. λ¨, λͺ¨λ λ©μλλ μΆμ λ©μλμ΄μ΄μΌ νλ€.
μΈν°νμ΄μ€λ₯Ό ꡬννλ ν΄λμ€λ μΈν°νμ΄μ€μμ μ μν νλ‘νΌν°μ μΆμ λ©μλλ₯Ό λ°λμ ꡬννμ¬μΌ νλ€.
// μΈν°νμ΄μ€μ μ μinterface IPerson {name: string;sayHello(): void;}/*μΈν°νμ΄μ€λ₯Ό ꡬννλ ν΄λμ€λ μΈν°νμ΄μ€μμ μ μν νλ‘νΌν°μ μΆμ λ©μλλ₯Ό λ°λμ ꡬννμ¬μΌ νλ€.*/class Person implements IPerson {// μΈν°νμ΄μ€μμ μ μν νλ‘νΌν°μ ꡬνconstructor(public name: string) {}// μΈν°νμ΄μ€μμ μ μν μΆμ λ©μλμ ꡬνsayHello() {console.log(`Hello ${this.name}`);}}function greeter(person: IPerson): void {person.sayHello();}const me = new Person('Lee');greeter(me); // Hello Lee
ν΄λμ€ νμ μ μΈν°νμ΄μ€λ₯Ό ꡬννλ ν΄λμ€μ μΌκ΄μ±μ μ μ§ν μ μλ μ₯μ μ κ°λλ€.
μΈν°νμ΄μ€ νμ₯
μΈν°νμ΄μ€λ extends
ν€μλλ₯Ό μ¬μ©νμ¬ μΈν°νμ΄μ€ λλ ν΄λμ€λ₯Ό νμ₯ν (μμ λ°μ) μ μλ€.
interface Person {name: string;age?: number;}interface Student extends Person {grade: number;}const student: Student = {name: 'Lee',age: 20,grade: 3};
λ€μμ μΈν°νμ΄μ€ λμ νμ₯
μΈν°νμ΄μ€λ λμμ νλ μ΄μμ μΈν°νμ΄μ€λ₯Ό νμ₯(μμ)ν μ μλ€. νμ₯ λμμ΄ λλ μΈν°νμ΄μ€λ€μ ,
μΌλ‘ ꡬλΆνλ€.
interface Person {name: string;age?: number;}interface Developer {skills: string[];}// λͺ¨λ νμ₯ λμ μΈν°νμ΄μ€μ μμ±μ μμ μ μμ±μ λν νμ μ κ°λλ€.interface WebDeveloper extends Person, Developer {}const webDeveloper: WebDeveloper = {name: 'Lee',age: 20,skills: ['HTML', 'CSS', 'JavaScript']};
νμ₯ λμμΈ μΈν°νμ΄μ€ μ€ μ¬λ¬ μΈν°νμ΄μ€κ° κ°μ μ΄λ¦μ μμ±μ κ°μ§ μ μμ§λ§ μ΄λ¦μ΄ κ²ΉμΉλ μμ±μ νμ μ λͺ¨λ νμ₯ λμ μΈν°νμ΄μ€μμ κ°μμΌ νλ€. κ°μ μ΄λ¦μ μμ±μ΄ λ€λ₯Έ νμ μ κ°λ κ²½μ° νμ μλ¬κ° λ°μνλ€.
ν΄λμ€λ₯Ό νμ₯ν μΈν°νμ΄μ€
μΈν°νμ΄μ€λ μΈν°νμ΄μ€ λΏλ§ μλλΌ ν΄λμ€λ νμ₯(μμ)ν μ μλ€.
ν΄λμ€μ λͺ¨λ λ©€λ²(public, protected, private)κ° μμλμ§λ§ ꡬνκΉμ§ μμνμ§ μλλ€.
class Person {constructor(public name: string, public age: number) {}}// μΈν°νμ΄μ€μ ν΄λμ€ μμinterface Developer extends Person {skills: string[];}const developer: Developer = {name: 'Lee',age: 20,skills: ['HTML', 'CSS', 'JavaScript']};
μμ½
- μΈν°νμ΄μ€μ μ μΈλ νλ‘νΌν° λλ λ©μλμ ꡬνμ κ°μ νμ¬ μΌκ΄μ±μ μ μ§ν μ μλ€.
- μΈν°νμ΄μ€λ₯Ό νμ μΌλ‘ μ¬μ©νλ©΄ ν΄λΉ μΈν°νμ΄μ€κ° κ°μ§ νλ‘νΌν°λ₯Ό λ°λμ ꡬνν΄μΌνλ€.
?
λ₯Ό νλ‘νΌν° μ΄λ¦ λμ λΆμ¬ κ°μ ν νμ§ μλ μ΅μ λ νλ‘νΌν°λ νν κ°λ₯νλ€.readonly
ν€μλλ₯Ό μ¬μ©ν΄μ μ¬ν λΉμ΄ λΆκ°λ₯ν μ½κΈ°μ μ© νλ‘νΌν° νν ν μ μλ€. (const
'λΉμ·' νλ€)- μΈλ±μλΈ νμ μ μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©ν΄ λμ μ΄κ³ μμΈ κ°λ₯ν κ°μ²΄ νμ μ μ μν κ² μ΄λ€.
- ν¨μ νμ μ νΈμΆ μκ·Έλμ²λ₯Ό μ¬μ©ν΄ νμ μ΄ μ μΈλ νλΌλ―Έν° 리μ€νΈμ λ¦¬ν΄ νμ μ μ μν κ² μ΄λ€.
- νΈμΆ μκ·Έλμ²μ νλ‘νΌν° νμ μ μλ₯Ό λμμ κ°λ μΈν°νμ΄μ€λ₯Ό νμ΄λΈλ¦¬λ νμ (hybrid type)λΌ νλ€.
implements
λ€μ μΈν°νμ΄μ€λ₯Ό μ¬μ©νλ©΄ ν΄λΉ ν΄λμ€λ μ§μ λ μΈν°νμ΄μ€λ₯Ό λ°λμ ꡬννμ¬μΌ νλ€.- μΈν°νμ΄μ€λ λ©μλλ ν¬ν¨ ν μ μμ§λ§, μΆμ λ©μλμ΄μ΄μΌ νλ€.
- μΈν°νμ΄μ€λ νλ‘νΌν°μ λ©μλλ₯Ό κ°μ§ μ μλ€λ μ μμ ν΄λμ€μ μ μ¬νλ μ§μ μΈμ€ν΄μ€λ₯Ό μμ±ν μλ μλ€.
- μΈν°νμ΄μ€λ
extends
ν€μλλ₯Ό μ¬μ©νμ¬ μΈν°νμ΄μ€ λλ ν΄λμ€λ₯Ό μμ λ°μ μ μκ³ , λ€μμ μΈν°νμ΄μ€λ₯Ό λμμ μμ λ°μ μλ μλ€.
ν μ€ μμ½
μΈν°νμ΄μ€λ μΌλ°μ μΌλ‘ νμ 체ν¬λ₯Ό μν΄ μ¬μ©λλ©° λ³μ, ν¨μ, ν΄λμ€μ μ¬μ©ν μ μκ³ , μ¬λ¬κ°μ§ νμ μ κ°λ νλ‘νΌν°λ‘ μ΄λ£¨μ΄μ§ μλ‘μ΄ νμ μ μ μνλ κ²κ³Ό μ μ¬νλ€.
reference
νμ
μ€ν¬λ¦½νΈ: νΈλλΆ - μΈν°νμ΄μ€ / TypeScript: Handbook - Interfaces
(λ€λ¬κΈ°λ νμ§λ§ λ²μκΈ°λ₯Ό μ¬μ©ν λ―ν λ¬Έμ₯μ΄ λ§μΌλ μλ³Έκ³Ό κ°μ΄ μ½λκ² μ’λ€)
TypeScript - Interface | PoiemaWeb
4.1 μΈν°νμ΄μ€ κΈ°μ΄ - ts-for-jsdev