ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (TypeScript) - 객체 타입 호환성
    개발/TypeScript 2025. 8. 20. 11:20
    반응형

    ■ 객체 타입 호환성

    /**
     * 객체 타입간의 호환성
     * -> 어떤 객체타입을 다른 객체타입으로 취급해도 괜찮은가?
     */
    
    type Animal = {
        name: string;
        color: string;
    };
    
    type Dog = {
        name: string;
        color: string;
        bread: string;
    };
    
    let animal: Animal = {
        name: '기린',
        color: 'yellow',
    };
    
    let dog: Dog = {
        name: '돌돌이',
        color: 'brown',
        bread: '진도',
    };
    
    animal = dog; //가능
    dog = animal; //불가능

     

    객체 타입도 기본 타입과 동일하게 어떤 객체타입을 다른 객체 타입으로 취급해도 되는지 호환성을 가진다.

     

    즉 여기서도 animal = dog; 가능하지만,

    그 반대는 불가능하다.

    따라서 animal 이 dog 타입보다 슈퍼 타입인 것이다.

    이는 각 객체의 프로퍼티에 따라 슈퍼 타입인지 서브 타입인지 결정한다.

     

    여기서는 dog 는 animal 의 모든 프로퍼티를 가지면서 추가적으로 bread 라는 추가 프로퍼티를 가진다.

    animal 은 여기서 name 과 color 가 있는 것은 다 animal 타입이라고 인식하기 때문에 dog 타입도 animal 타입이 되고,

    dog 타입이 animal 타입의 부분 집합이 되는 것이다.

     

    즉, 프로퍼티가 더 적은 타입이 슈퍼 타입이 되는 것이다.

     

    type Book = {
        name: string;
        price: number;
    };
    
    type ProgramingBook = {
        name: string;
        price: number;
        skill: string;
    };
    
    let book: Book;
    let programingBook: ProgramingBook = {
        name: '한 입 크기로 잘라먹는 리액트',
        price: 33000,
        skill: 'reactjs',
    };
    
    book = programingBook;
    //programingBook = book; 다운캐스팅 불가!

     

    또 다른 예제에서도 다운캐스팅이 안되는 것을 확인할 수 있다.

     

    /**
     * 초과 프로퍼티 검사
     *
     */
    let book2: Book = {
        name: '한 입 크기로 잘라먹는 리액트',
        price: 33000,
        skill: 'reactjs',
    };

     

    그런데 이렇게 book 안에 programingBook 넣을 수 있음에도 불구하고

    새로운 Book 타입을 정의했을 때 programingBook 에만 있는 프로퍼티를 넣으면 오류가 발생한다.

     

    그 이유는 초과 프로퍼티 검사를 진행하기 때문이다.

     

    초과 프로퍼티 검사란 변사를 초기화 할 때, 초기화하는 값으로 객체 리터럴을 사용하면 발동하는 검사로,

    실제 타입에는 정의하지 않은 프로퍼티를 넣는 것을 막는 검사이다.

     

    따라서 객체 타입 초기화 시에는 객체 타입에 정의된 프로퍼티만 넣을 수 있다.

    let book3: Book = programingBook

     

    따라서 방법은 2가지가 있다.

     

    객체 리터럴 {} 을 사용해서 초기화 할 때는 정해진 타입만 정의하거나,

    아니면 객체 리터럴 타입이 아닌 아래 코드처럼 할당해주면 된다.

     

    let book3: Book = programingBook;
    
    function func(book: Book) {
        func({
            name: '한 입 크기로 잘라먹는 리액트',
            price: 33000,
            skill: 'reactjs', // 오류 발생
        });
    }
    
    func(programingBook) // 가능

     

    함수에 객체를 할당할 때도 객체 리터럴로 전달 시에는 오류가 뜨므로

    programingBook 를 func 의 인수로 전달해줘야 한다. 

     

    반응형
Designed by Tistory.