728x90
인터페이스
// 인터페이스
interface Person {
name: string;
age: number;
}
const person: Person = {
name: "이정환",
age : 27
};
- 타입 별칭처럼 타입의 이름을 지어주는 문법으로 상호간에 약속된 규칙
- 상속, 합침 등의 특수한 기능을 제공해 객체의 구조를 정의하는 데 더 특화된 문법
interface Person {
readonly name: string;
age?: number;
}
const person: Person = {
name: "summermong",
// age: 27,
};
person.name = 'wintermong' // 읽기 전용으로 수정 불가
- 선택적 프로퍼티 설정도 동일하게 사용 가능하다.
- 읽기 전용 키워드인 readonly로 수정을 불가하게 할 수도 있다.
interface Person {
readonly name: string;
age?: number;
sayHi: () => void; // sayHi(): void; 와 같이 호출 시그니처 사용 가능
}
- 함수 타입 표현식으로 sayHi 메서드의 타입을 정의했다.
- 호출 시그니처를 사용해서 메서드의 타입을 정의할 수도 있다.
// 함수 타입 표현식으로 메서드 타입 정의 시 오버로딩 구현 불가
interface Person {
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;
}
- sayHi 메서드 타입을 정의할 때 함수 타입 표현식으로 하면 중복된다고 이해, 오버로딩 구현이 불가하다.
- 이 때 호출 시그니처로 정의하면 오버로딩 구현이 가능하다.
type Type1 = number | string;
type Type2 = number & string;
interface Person {
name: string;
age: number;
} | number // ❌
- 인터페이스는 타입 별칭과 대부분 비슷하게 동작하지만, 유니온이나 인터섹션 타입을 정의할 수 없다.
type Type1 = number | string | Person;
type Type2 = number & string & Person;
const person: Person & string = {
name: "summermong",
age: 27,
};
- 인터페이스로 만든 타입을 유니온, 인터섹션으로 이용해야 한다면 타입 별칭과 사용하거나 타입 주석에 직접 기입해야 한다.
인터페이스 확장 (상속)
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;
}
- 중복되는 프로퍼티를 계속 작성하는 것은 비효율적이다.
- 또 Animal 타입의 프로퍼티 1개가 변경되면 다 변경해야 해서 유지보수가 어렵다.
- 이렇게 특정 인터페이스를 기반으로 여러 개의 인터페이스가 파생되는 경우 확장 기능을 사용한다.
interface Animal {
name: string;
color: string;
}
interface Dog extends Animal {
breed: string;
}
interface Cat extends Animal {
isScratch: boolean;
}
interface Chicken extends Animal {
isFly: boolean;
}
- extends 뒤에 확장할 타입의 이름을 정의하면 해당 타입에 정의된 모든 프로퍼티를 다 가지고 오게 된다.
interface Animal {
name: string;
color: string;
}
interface Dog extends Animal {
isBark: boolean;
}
const dog: Dog = {
name: '',
color: '',
isBark: true,
};
- Animal 타입이 있고 Animal 타입을 상속 받은 Dog 타입이 있다.
- 객체 dog의 타입이 Dog 타입이라면 Animal은 Dog 타입의 슈퍼 타입이 된다.
interface Animal {
name: string;
color: string;
}
interface Dog extends Animal {
// name: '주몽' // 에러 발생
isBark: boolean;
}
const dog: Dog = {
name: '',
color: '',
isBark: true,
};
- Animal 타입의 name이 string이고, 여기서 확장된 Dog 타입의 name이 string 리터럴이면 에러가 발생한다.
- 프로퍼티를 재정의 할 때, 원본 타입을 A, 재정의된 타입을 B라고 할 때 반드시 A가 B의 슈퍼 타입이 되도록 해야 한다.
type Animal = {
name: string;
color: string;
};
interface Dog extends Animal {
breed: string;
}
- 추가로 인터페이스는 같은 인터페이스끼리 뿐만 아니라 타입 별칭으로 정의된 객체도 확장할 수 있다.
interface DogCat extends Dog, Cat {}
const dogCat: DogCat = {
name: "",
color: "",
breed: "",
isScratch: true,
};
- 또 하나의 인터페이스만 확장할 수 있는 게 아니라 여러 개의 인터페이스를 확장하는 것도 가능하다.
인터페이스 선언 합침 (declaration merging)
interface Person {
name: string;
}
interface Person {
age: number;
}
const person: Person = {
name: '',
age: 27,
};
- 타입 별칭은 동일한 스코프 내에 중복된 이름으로 선언할 수 없지만, 인터페이스는 가능하다.
- 그 이유는 중복된 이름의 인터페이스 선언은 하나로 합쳐지기 때문이다.
- 이렇게 동명의 인터페이스가 합쳐지는 것을 선언 합침이라고 부른다.
interface Person {
name: string;
}
interface Person {
name: number;
age: number;
}
- 단, 이런 선언 합침은 프로퍼티의 타입이 반드시 같아야 한다. (서브 타입도 불가)
- 이렇게 동일한 프로퍼티의 타입을 다르게 정의한 상황을 충돌이라고 하며, 선언 합침에서 이러한 충돌은 허용되지 않는다.
**출처: 한 입 크기로 잘라먹는 타입스크립트 (인프런, 이정환 강사님)
728x90
'❔ TypeScript > 💭 한 입 크기 TypeScript' 카테고리의 다른 글
[TypeScript] 접근 제어자 (0) | 2023.12.21 |
---|---|
[TypeScript] 타입스크립트의 클래스 (0) | 2023.12.21 |
[TypeScript] 함수 타입 (1) | 2023.12.19 |
[TypeScript] 타입스크립트 이해하기 (1) | 2023.12.18 |
[TypeScript] 타입스크립트의 기본 타입 정리 (0) | 2023.12.16 |