인터페이스와 타입별칭의 차이점
- 확장여부 : 인터페이스는 extends를 통해 상위인터페이스로부터 상속받아 확장가능하다. 그러나, 타입별칭은 &를 이용한다.
- 병합여부 : 인터페이스는 여러군데에서 선언해서 병합가능하나 타입별칭은 한군데에서 선언한다.
// 필수속성은 pages, 선택속성은 author
interface Book {
pages: number;
author?: string;
}
const missing: Book = {
pages: 80,
};
console.log(missing.author) // undefined
// 읽기전용 속성
interface Page {
readonly text: string;
}
function read(page: Page) {
console.log(page.text); // Ok
page.text += '!'; // Error: Cannot assign to 'text' because it is a read-only property.
}
method() : stringproperty: () => string;(input : string) => number(input : string) : number[key : type] : type// 정의
interface WordCounts {
[i: string]: number;
}
const counts: WordCounts = {};
counts.apple = 0;
counts.banana = 1;
counts.cherry = true; //Error
멤버접근시 해당 속성이 없으면 새로 생성된다. 따라서, 인덱스 시그니처를 사용하면 프로퍼티의 존재유무를 알 수 없다.키-쌍을 저장하려는데 키를 미리 알 수 없다면 Map을 사용하는 것이 안전하다.
// 값 할당
interface DateByName {
[i: string]: Date;
}
const a: DateByName = {
frank: new Date("1 January 1818"),
};
a.frank; // 타입은 Date
a.hello; // 타입은 Date, 런타임은 undefined
console.log(a.frank, a.hello); // 1817-12-31T15:32:08.000Z undefined
// 객체로 매핑하여 관리
interface Counts {
[key: string]: number
}
const counts: Counts = {};
counts.apple = 3;
counts.banana = 5;
function setCount(counts: Counts, fruit: string) {
counts[fruit] += 10;
}
setCount(counts, 'peach');
console.log(counts);
// {
// "apple": 3,
// "banana": 5,
// "peach": null
// }
// 속성과 인덱스 시그니처 혼합
interface history {
oro: number;
[i: string]: number | string; // 명명된 속성의 타입 할당
}
const novels: history = { out: 1991, oro: 1688 };
const missing: history = { out: 1991 }; // Property 'oro' is missing in type '{ out: number; }' but required in type 'history'.
const konovels: history = { out: 1991, in: "in", oro: 1688 }; // 명명된 속성의 타입이 인덱스 시그니처에 할당될 수 있는 경우 더 구체적인 타입을 지정
interface More {
[i: number]: string;
[i: string]: string | undefined;
}
// interface More {
// [i: number]: string | undefined;
// [i: string]: string // Error : 최소한 string | undefined를 가져야함
// }
const mixed: More = {
0: "",
key1: "",
key2: undefined,
};
extends 키워드를 이용하여 확장한다. (,를 이용해 다중확장 가능)// 인터페이스 확장시 하위 인터페이스의 속성 : 상위를 모두 포함하여!
interface writing {
title: string;
}
interface nov extends writing {
pages: number;
}
let mynove: nov = {
title: "hi",
pages: 200,
};
// 인터페이스 확장시 하위 인터페이스의 속성타입 : 상위보다 더 좁게!
interface A {
name: string | null | number;
}
// 상속받은 타입중에서만 타입 재정의가 가능하다.
interface B extends A {
name: string;
}
interface Merged {
name: string;
}
interface Merged {
age: number;
}
// 즉,
// interface Merged{
// name : string
// age :number
// }
let merged: Merged = { name: "1", age: 1 };