[TypeScript] 구조적 서브타이핑

김지훈·2024년 4월 26일
0

TypeScript 스터디

목록 보기
1/10
post-thumbnail

🔗 TypeScript의 구조적 서브타이핑에 대한 공식 문서

TypeScript의 타입 호환성은 구조적 서브 타이핑(subtyping)을 기반으로 합니다. 구조적 타이핑이란 오직 멤버만으로 타입을 관계시키는 방식입니다. 명목적 타이핑(nominal typing) 과는 대조적입니다.

구조적 서브타이핑은 타입스크립트의 타입 시스템을 지탱하고 있는 개념으로, 이름이 다른 객체라도 동일한 속성을 가지고 있다면, 타입스크립트는 서로 호환이 가능한 동일한 타입으로 취급한다.


interface Named {
    name: string;
}
let x: Named;
// y의 추론된 타입 { name: string; location: string; }
let y = { name: "Alice", location: "Seattle" };
x = y; // 성공
y = x; // 실패
  • 위 코드에서 yname이라는 속성을 가지고 있으므로, Named 타입으로 선언한 xy를 할당할 수 있다. 단, 반대의 경우는 성립하지 않는다. x에는 location이라는 속성이 없기 때문이다.
function greet(n: Named) {
    console.log("Hello, " + n.name);
}
greet(y); // 성공
  • 함수의 매개변수에 대해서도 동일한 방식으로 적용된다.

let x = (a: number, s: string) => 0;
let y = (b: number) => 0;
x = y; // 성공
y = x; // 실패
  • 위 경우에서는 yx에 할당할 수 있는지 검사하기 위해, 먼저 매개변수 목록을 살펴본다. 매개변수의 이름은 고려하지 않고 타입만 검사한다. 이 경우에는 y의 모든 매개변수는 x에 상응하는 호환 가능한 매개변수를 가지므로 할당이 허용된다.
  • 반대로, xy에 없는 매개변수를 가지고 있기 때문에 할당이 허용되지 않는다.

  • 함수에 인자로 객체 리터럴을 바로 전달하는 경우에는 타입 호환을 지원하지 않는다.
class Person {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
}

class Developer {
    name: string;
    age: number;
    sleepTime: number;

    constructor(name: string, age: number, sleepTime: number) {
        this.name = name;
        this.age = age;
        this.sleepTime = sleepTime;
    }
}

function greet(p: Person) {
    console.log(`Hello, I'm ${p.name}`);
}

const developer = new Developer("jihun", 24, 7);
greet(developer); // 성공

greet({
    name: "heonseok",
    age: 27,
    sleepTime: 5;
}); // 실패

0개의 댓글