interface User {
name: string;
age: number;
}
const human: User = {
name: "홍길동",
age: 20
};
선택적 프로퍼티 (Optional Properties)
? 를 붙여 선택사항으로 정의interface User {
name: string;
age?: number; // age는 필수가 아님
}
읽기 전용 프로퍼티 (Readonly Properties)
readonly 키워드를 붙여 정의interface User {
readonly id: number;
name: string;
}
인터페이스 확장 (Extension)
extends를 사용하여 기존 인터페이스를 복사하고 새로운 속성을 추가(확장), 를 구분자로 여러개의 인터페이스를 확장하는 것 또한 가능// ---------------------
// 인터페이스의 확장
// ---------------------
interface Animal {
name: string;
}
// interface `Human`은 interface `Animal`을 확장하여 정의
interface Human extends Animal {
age: number;
}
// `Human`은 `Animal`을 확장하여 사용하고 있으므로 프로퍼티 `name`도 사용 가능
let human: Human = {
age: 20,
name: 'Hong'
};
// ---------------------
// 인터페이스의 다중 확장
// ---------------------
interface Douner extends Animal, Human {
kinds: string;
}
let douner: Douner = {
age: 20,
name: 'Douner',
kinds: 'Alien'
}
선언 병합 (Declaration Merging)
// 결과적으로 Interface `Animal`을 `name`과 `age` 모두 가진 Interface가 됨
interface Animal { name: string; }
interface Animal { age: string; }
// 주의: 동일한 프로퍼티에 다른 타입일 경우는 에러가 발생
interface Dog { name: string; age: string; }
// Error: Subsequent property declarations must have the same type.
// Property 'age' must be of type 'string', but here has type 'number'.
interface Dog { age: number; }
메소드 정의
함수 타입 프로퍼티 (Function Type Property) 방식
메서드 시그니처 (Method Signature) 방식
interface Animal { name: string; }
interface Human extends Animal { age: number; }
// 함수 타입 프로퍼티로 정의
interface StrictBarking {
barking: (arg: Animal) => void;
}
// 메서드 시그니처로 정의
interface LooseBarking {
barking(arg: Animal): void;
}
// 테스트용 함수(`Human`보다 더 넓은 `Animal`타입으로 파라미터 정의)
let animalBarking = (arg: Human) => {
console.log(arg.name);
};
// 함수 타입 프로퍼티: 더 좁은 타입(Human)을 처리하는 함수를 더 넓은 타입(Animal)을 기대하는 곳에 할당하여 에러
//Error:
// Type '(arg: Human) => void' is not assignable to type '(arg: Animal) => void'.
// Types of parameters 'arg' and 'arg' are incompatible.
// Property 'age' is missing in type 'Animal' but required in type 'Human'.
let strictBarking: StrictBarking = { barking: animalBarking };
// 메서드 시그니처: 타입이 조금 달라도(더 좁아도) 일단 허용
let looseBarking: LooseBarking = { barking: animalBarking };
메소드 오버로딩(Method Overloading)
오버로딩을 표현하려면 반드시 메소드 시그니처 방식을 사용
실무에서는 직접 만들 경우는 그렇게 많지 않으나, 라이브러리 사용을 위해 이해는 필요
// 함수 타입 프로퍼티 방식의 경우, 객체의 한 '속성'에 타입을 정의하는 것이므로
// 하나에 두 개의 타입을 동시에 할당 불가
interface Animal {
// Error: Duplicate identifier 'baking'.
baking: () => void;
baking: (msg: string) => void;
}
// 메소드 시그니처 방식으로 오버로딩 구현
interface Human {
baking(): void;
baking(msg: string): void;
}
특수한 타입(Union, Tuple 등)이 필요한 게 아니라면, 기본적으로 interface를 사용 권장
| 특징 | 인터페이스 (Interface) | 타입 별칭 (Type Alias**)** |
|---|---|---|
| 주 목적 | 객체의 구조 정의 | 모든 타입의 Alias 정의 |
| 확장 방식 | extends 키워드 사용 |
& (Intersection) 기호 사용 |
| 선언 병합 | 가능 (동일 이름 선언 시 합쳐짐) | 불가능 (에러 발생) |
| 사용 가능 범위 | 객체만 가능 | 원시값, 유니온 등 |
Interface를 추천하는 경우
Type Alias를 추천하는 경우
type Status = "success" | "error"; 처럼 여러 값 중 하나를 선택하는 타입을 만들 때type ID = string | number;