Typescript에서 인터페이스는 타입 들의 이름을 짓는 역할을 하고 코드 안의 계약을 정의하는 것 뿐만 아니라 프로젝트 외부에서 사용하는 코드의 계약을 정의하는 강력한 방법입니다.
다음 예제를 보겠습니다.
function printLabel(labeledObj: { label: string }) {
console.log(labeledObj.label);
}
let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
함수에 전달되는 객체가 실제로 size 프로퍼티를 더 가지고 있지만, 컴파일러는 최소한 필요한 프로퍼티가 있는지와 타입이 잘 맞는지만 검사합니다. Typescript가 관대하지 않은 몇 가지 경우는 나중에 다루겠습니다.
이번에는 같은 예제에 인터페이스를 사용해 보겠습니다.
interface LabeledValue {
label: string;
}
function printLabel(labeledObj: LabeledValue) {
console.log(labeledObj.label);
}
let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
이전 예제와 동일하게 두 예제는 잘 작동합니다. 다른 언어처럼 전달하는 객체가 이 인터페이스를 구현해야 한다고 명시적으로 얘기하지 않습니다. 여기서 중요한 것은 형태 뿐입니다.
프로퍼티 이름 앞에 readonly
를 넣어서 이를 지정할 수 있습니다.
interface Point {
readonly x: number;
readonly y: number;
}
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // 오류!
Typescript에서는 모든 mutating 메소드가 제거된 ReadonlyArray<T>
타입을 제공합니다.
let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;
ro[0] = 12; // 오류!
ro.push(5); // 오류!
ro.length = 100; // 오류!
a = ro; // 오류!
마지막 줄을 보면 일반 배열에 재할당이 불가합니다. type assertion으로 가능하게 할 수 있습니다.