onebite TS - 5강. 인터페이스

박하늘·2025년 10월 21일

1️⃣ 인터페이스

  • 인터페이스란 타입 별칭과 동일하게 타입에 이름을 지어주는 또 다른 문법
  • 상호간에 약속된 규칙 이라는 뜻
  • 객체의 구조를 정의하는데 특화된 문법 (상속, 합침 등의 특수한 기능을 제공함)

interface Person {
  name: string;
  age: number;
  sayHi: () => void
  // sayHi(): void; 도 가능
  // 메서드 타입 정의
}

// ? / readonly 모두 사용 가능


const person: Person = {
    name: "박하늘",
    age: 25,
    sayHi: function () {
        console.log("안녕")
    }
    // 프로퍼티에 저장된 값이 함수인 것을 메서드 라고 한다
}

✴︎ 매개변수 여러 개 ...

person.sayHi();
person.sayHi(1,2);

만약 위와 같은 함수를 사용하고 싶을 때는

interface Person {
  name: string;
  age: number;
  sayHi: () => void
}
// ❌ - 위처럼 지정 해주면 매개변수 2개가 들어간 곳에는 에러 발생

interface Person1 {
  readonly name: string;
  age?: number;
  sayHi: () => void; 
  sayHi: (a: number, b: number) => void;
  // ❌ - 함수 표현식으로 정의 하는 것 또한 불가능
}



// ⭕️ - 아래처럼 호출 시그니처를 이용하여 메서드 타입 정의 하면 오버로딩 구현 가능

interface Person {
  readonly name: string;
  age?: number;
  sayHi(): void;
  sayHi(a: number): void;
  sayHi(a: number, b: number): void;
}

✴︎ 타입정의와 차이점

인터페이스는 Union 타입 또는 Intersection 타입 정의 불가능

type Type1 = number | string;
type Type2 = number & string;

// 타입 정의는 가능

interface Person {
  name: string;
  age: number;
} | number // ❌

따라서 인터페이스로 만든 타입을 Union 또는 Intersection으로 이용해야 한다면 다음과 같이 타입 별칭과 함께 사용하거나 타입 주석에서 직접 사용

type Type11 = number | string | Person;
type Type22 = number & string & Person;

const person: Person & string = {
  name: "이정환",
  age: 27,
};

2️⃣ 인터페이스 확장

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

interface Dog {
  name: string;
  age: number;
  isBark: boolean;
}

interface Cat {
  name: string;
  age: number;
  isScratch: boolean;
}

interface Chicken {
  name: string;
  age: number;
  isFly: boolean;
}

⚠️ name 그리고 age 프로퍼티가 모든 타입에 중복해서 정의

✴︎ 확장기능(상속) extends 사용

interface Animal {
  name: string;
  ages: number; // 수정
}

interface Dog extends Animal {
  isBark: boolean;
}

interface Cat extends Animal {
  isScratch: boolean;
}

interface Chicken extends Animal {
  isFly: boolean;
}

// 이렇게 사용 가능 !



// 만약 아래처럼 이름을 빈 문자열로 했는데
const dog: Dog = {
    name: "",
    color: "",
    isBark: true
}

// 아래처럼 이름은 고정으로 지정해주고 싶을 경우 ..
interface Dog extends Animal {
    name: "hello"
    // 꼭 원본 타입의 서브 타입이어야 한다
    // 원본 타입이 string 일 경우 "하늘" 가능하지만 123 불가
    // 이렇게 해주면 string 리터럴 타입으로 저장됨
  isBark: boolean;
}

✴︎ 다중 확장

interface DogCat extends Dog, Cat {}

const dogCat: DogCat = {
  name: "",
  color: "",
  isBark: true,
  isScratch: true,
};
// 또 여러개의 인터페이스를 확장하는 것 또한 가능합니다.


⚠️ 참고로 인터페이스는 인터페이스 뿐만 아니라 타입 별칭으로 정의된 객체도 확장할 수 있습니다.

[인터페이스가 타입 별칭을 확장] - 가능

// 타입 별칭으로 객체 타입 정의
type Animal = {
  name: string;
  color: string;
};

interface Dog extends Animal {
  isBark: boolean;
}

const dog: Dog = {
  name: "Max",
  color: "black",
  isBark: true,
};

[타입이 인터페이스를 확장] - 불가능

interface Animal {
  name: string;
  color: string;
}

// ❌ 불가능: type은 interface를 extends할 수 없음
type Dog = Animal & { isBark: boolean }; // ← 이런 식으로는 가능 (교집합)

3️⃣ 인터페이스 선언 합치기

import { Interface } from "readline";

type Person = {
  name: string;
};

type Person = { 
  age: number;
};
// ❌ - 타입 별칭은 동일한 스코프 내에 중복된 이름으로 선언할 수 없는 반면 인터페이스는 가능

interface Person1 {
  name: string;
}

interface Person1 { // ✅
  name: number; // ❌ 위에 선언이 되어 있는데 다른 타입으로 재선언 될 경우 충돌 에러. 타입을 맞추면 가능
  age: number;
}

// ⭐️ 다음과 같이 위에서 두 번 중복된 이름의 인터페이스 선언은 결국 모두 하나로 합쳐짐
interface Person1 {
	name: string;
	age: number;
}

const person: Person1 = {
  name: "이정환",
  age: 27,
};

// 이렇게 확장하는 타입에서는 해당 프로퍼티에 대한 타입이 서브타입일 경우 가능
interface Developer extends Person {
    name: "hello"
}

0개의 댓글