front-end / / 2023. 11. 27. 06:46

[typescript] 인터페이스

이 내용은 코드앙마의 타입스크립트 강좌를 정리해놓은 자료이다.

코드앙마 타입스크립트


object 속성

let user:object;

user = {
    name: 'xx',
    age: 30
}

user를 object 타입으로 정의를 하고 콘솔에서 name을 찍어보면 에러가 발생한다.

console.log(user.name); // 에러 발생

object에는 특정 속성값에 대한 정보가 없기 때문이다.

이렇듯 property를 정의해서 나타낼 때는 인터페이스를 사용한다.

인터페이스 정의

interface User {
    name : string;
    age : number;
}

let user : User = {
    name : 'xx',
    age : 30
}

User 인터페이스를 정의하고 user 값을 사용해 보자.

user.age = 10; // 이건 문제가 없고
user.gender = "male"; // 이건 오류가 발생

이건 gender가 없어서 발생하는 문제이다.

interface User {
    name : string;
    age : number;
}

let user : User = {
    name : 'xx',
    age : 30
}

gender를 추가해보자. gender는 값이 있어도 되고 없어도 되는 optional로 처리를 해보자.

interface User {
    name : string;
    age : number;
    gender?: string; // optional로 처리
}

let user : User = {
    name : 'xx',
    age : 30
}

user.age = 10;
user.gender = "male"; 

gender는 optional로 지정했기 때문에 gender가 없어도 되지만 gender가 있을 때는 string이어야 한다.

다음은 readonly property를 만들어보자. 읽기 전용이다.

interface User {
    name : string;
    age : number;
    gender?: string; 
    readonly birthday : number; // 읽기전용으로 설정
}

let user : User = {
    name : 'xx',
    age : 30,
    birthday : 2000,
}

user.age = 10;
user.gender = "male"; 
user.birthday = 1990; // 여기서 오류가 발생한다.

user.birthday에서 수정할 때 오류가 발생한다.
readonly는 생성할 때만 할당이 가능하고 그 이후 수정이 불가능하다.

그 다음은 학년별로 점수를 기록하고 싶다고 하자.

interface User {
    name : string;
    age : number;
    gender?: string; 
    readonly birthday : number;
    1? : string;
    2? : string;
    3? : string;
    4? : string;
}

let user : User = {
    name : 'xx',
    age : 30,
    birthday : 2000,
    1 : 'A',
    2 : 'B',
    3 : 'C'
}

이렇게 각 학년별로 optional로 지정하면 특정 학년의 값을 할당할 수 있다.

이렇게 하지 말고 문자열 인덱스로 추가하는 방법을 알아보자.

interface User {
    name : string;
    age : number;
    gender?: string; 
    readonly birthday : number;
    [grade: number] : string;
}

let user : User = {
    name : 'xx',
    age : 30,
    birthday : 2000,
    1 : 'A',
    2 : 'B'
}

이렇게 [grade:number] 형식으로 정의할 수 있다. grade가 의미있는 값은 아니고 number 타입의 임의의 변수를 의미한다. grade를 다른 문자열로 지정해도 상관없다.

그리고 [grade: number] : string에서 성적을 숫자로 받기에는 범위가 너무 넓다. 이럴 때 사용하는 것은 문자열 리터럴 타입이다.

type Score = 'A' | 'B' | 'C' | 'F';  // type을 지정

interface User {
    name : string;
    age : number;
    gender?: string; 
    readonly birthday : number;
    [grade: number] : Score; // Score로 변경
}

let user : User = {
    name : 'xx',
    age : 30,
    birthday : 2000,
    1 : 'A',
    2 : 'B'
}

위에서 grade를 Score로 변경한다. Score에 해당하는 값만 넣을 수 있다.

인터페이스로 함수 정의

인터페이스로 함수도 정의할 수 있다.

interface Add {
    (num1:number, num2: number) : number
}

const add : Add = function(x, y) {
    return x + y;
}

이를 사용하면

add(10, 20); // 정상
add(10, '20'); // 문자열로 넣으면 오류 발생

다음은 나이를 받아서 성인인지 여부를 리턴하는 함수를 만들어보자.

interface IsAdult {
    (age:number):boolean;
}

const a:IsAdult = (age) => {
    return age > 19;   
}

a(33); // true

인터페이스로 클래스 정의

인터페이스로 클래스도 정의할 수 있다.

// Car 인터페이스를 정의하고
interface Car {
    color: string;
    wheels: number;
    start(): void
}

// Car를 구현하는 클래스를 정의
class Bmw implements Car {
    color;
    wheels = 4;

    constructor(c: string) {
        this.color = c;
    }
    start() {
        console.log('go...')
    }
}

// Car 객체를 생성
const b = new Bmw('green');
console.log(b);
b.start(); // go...가 잘 출력된다.

인터페이스 확장

인터페이스는 확장이 가능하다.

interface Car {
    color: string;
    wheels: number;
    start(): void
}

// Car를 확장
interface Benz extends Car {
    door: number;
    stop(): void;
}

const benz : Benz = {
    door: 5,
    stop() {
        console.log('stop');
    },
    color: 'black',
    wheels: 4,
    start() {
        console.log('go...')
    }
}

참고로 확장은 여러 개를 할 수도 있다.

interface Car {
    color: string;
    wheels: number;
    start(): void
}

interface Toy {
    name: string;
}

// Car와 Toy를 모두 확장하는 경우에 사용
interface ToyCar extends Car, Toy {
    price: number;
}
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유