본문 바로가기
TYPESCRIPT

인터페이스

by 일태찡 2023. 3. 23.

 

인터페이스란

 

인터페이스는 객체의 형태를 설명하는 데 사용할 수 있습니다.

클래스와 달리 인터페이스는 청사진으로 사용하지 않고 사용자 정의 타입으로 사용할 뿐입니다.

 

interface Person {
    name: string;
    age: number;

    // 메서드
    greet(phrase: string): void
}

 

기본값을 할당하려 하면 다음과 같은 에러가 발생합니다.

 

 

구체적인 값이 아닌 구조만 있을 뿐입니다.

 

interface Person {
    name: string;
    age: number;

    greet(phrase: string): void
}

let user1: Person;

user1 = {
    name: 'KIM',
    age: 29,
    greet(phrase: string) {
        console.log(phrase + ' ' + this.name)
    }
}

 

이렇게 인터페이스를 이용하여 객체의 구조를 정의할 수 있게 해 줍니다.

 

 

사용자 정의 타입과 인터페이스

 

interface Greetable {
    readonly name: string;
    greet(phrase: string): void
}

 

 type Greetable = {
    readonly name: string;
    greet(phrase: string): void
}

 

위 두 예시 인터페이스와 타입 지정은 사실 똑같이 작동합니다.

종종 두 개를 바꿔가며 써도 대부분 잘 작동하지만 차이가 조금 있습니다.

가장 큰 차이점 하나는 타입 지정과는 다르게 인터페이스는 객체의 구조를 설명하기 위해서만 사용한다는 것입니다.

또, 클래스에서 객체 유형을 정의할 때 타입 지정 대신 인터페이스를 사용하는 것이 좋습니다.

이는 인터페이스를 이행하고 준수해야 하는 약속처럼 사용할 수 있기 때문입니다.

 

 

클래스와 인터페이스

 

인터페이스는 주로 구체적인 구현이 아닌 서로 다른 클래스 간의 기능을 고유하기 위해 사용됩니다.

즉, 인터페이스 내에 구현이나 값을 입력하는 게 아닌 구조와 클래스가 가져야 할 기능을 입력해야 합니다.

인터페이스에는 구현 세부 사항이 전혀 없는 반면, 추상 클래스는 덮어써야 했던 부분과 구체적 구현 부분을 혼합할 수 있습니다.

 

interface Greetable {
    name: string;

    greet(phrase: string): void
}

class Person implements Greetable {
    name: string;
    age= 30;

    constructor(n: string) {
        this.name = n;
    }

    greet(phrase: string) {
        console.log(phrase + ' ' + this.name)
    }
}

let user1: Greetable;

user1 = new Person('KIM');

 

 

읽기 전용 인터페이스 속성

 

인터페이스에 readonly 제어자를 추가할 수 있습니다. 다만 public, private 등은 지정할 수 없습니다.

 

interface Greetable {
    readonly name: string;

    greet(phrase: string): void
}

class Person implements Greetable {
    name: string;
    age= 30;

    constructor(n: string) {
        this.name = n;
    }

    greet(phrase: string) {
        console.log(phrase + ' ' + this.name)
    }
}

let user1: Greetable;

user1 = new Person('KIM');
user1.name = 'PARK'; // 에러

 

인터페이스에 readonly 속성을 적용하면 클래스에 따로 더 적지 않아도 자동으로 추론합니다.

따라서 위 예시 같이 name에 새로운 값을 할당하고자 할 때 다음과 같은 에러가 발생합니다.

 

 

 

인터페이스 확장하기

 

interface Named {
    readonly name: string;
}

interface Greetable {
    greet(phrase: string): void
}

class Person implements Greetable, Named {
...
}

 

이렇게 두 개의 인터페이스를 클래스에 적용할 수 도 있고

 

interface Named {
    readonly name: string;
}

//                               , 여기도 여러개 가능
interface Greetable extends Named {
    greet(phrase: string): void
}

class Person implements Greetable {
...
}

 

하나의 인터페이스로 결합할 수 도 있습니다.

클래스의 상속과 가장 큰 차이점은 클래스는 하나의 클래스로부터만 상속할 수 있고 다수의 클래스로부터는 상속할 수 없지만 인터페이스의 경우 여러 인터페이스로부터 상속받을 수 있습니다.

 

 

함수 타입으로서의 인터페이스

 

함수도 결국 객체이기 때문에 타입 지정 대신 인터페이스를 사용할 수 있습니다.

 

// type AddFn = (a: number, b: number) => number;
interface AddFn {
    (a: number, b:number): number;
}

let add: AddFn;

add = (n1: number, n2:number) => {
    return n1 + n2;
}

 

 

선택적 매개변수 & 속성

 

속성 이름 다음에 물음표를 추가하여 선택적 속성을 지정할 수 있습니다.

그러면 타입스크립트는 이 속성이 인터페이스를 구현하는 클래스 내에 있을 수 있지만 반드시 그렇지는 않다고 인식하게 됩니다.

필수 사항을 선택 사항으로 바꾸게 하는 것입니다.

 

interface Named {
    readonly name?: string;
    outputName?: string;
}

interface Greetable extends Named {
    greet(phrase: string): void
}

class Person implements Greetable {
    // 선택적 속성
    name?: string;
    age= 30;

    // 인자가 선택사항이 됨
    constructor(n?: string) {
        if(n) {
            this.name = n;
        }
    }

    greet(phrase: string) {
        if(this.name) {
            console.log(phrase + ' ' + this.name);
        } else {
            console.log('No Name!');
        }
    }
}

let user1: Greetable;

user1 = new Person(); // 인자 없이 오류 X

 

위의 코드와 같이 속성 마지막에 ?를 적어 선택적 속성을 부여할 수 있습니다.

인터페이스와 클래스에서 name 속성을 선택적으로 만들었고 생성자 함수 매개 변수를 선택적으로 만들어 새 인스턴스를 생성할 때 인자가 없어도 가능하게 하였습니다.

인자 없이 인스턴스 생성을 가능하게 하기 위해선 매개 변수에 기본값을 넣어주거나 선택적 매개변수로 만들어줘야 합니다.

 

 

++

 

인터페이스는 자바스크립트로 컴파일 도중 코드를 검사하는 데만 사용된 다음에 무시됩니다.

즉 컴파일된 자바스크립트 코드를 보면 인터페이스의 흔적을 찾아볼 수 없습니다.

'TYPESCRIPT' 카테고리의 다른 글

제네릭  (6) 2023.03.27
고급 타입  (6) 2023.03.24
클래스 2  (6) 2023.03.21
클래스 1  (6) 2023.03.20
타입스크립트 컴파일러  (7) 2023.03.17