인터페이스는 구현 함수를 호출하는 쪽에서 필수 인수인 text와 capitalize를 모두 전달하도록 요구합니다.
TypeScript는 JavaScript가 쓰지 않는 추가 인수를 받아도 괜찮다는 걸 알기 때문에 구현에서 그 인수를 생략하도록 허용합니다.
왜 괜찮을까요? 호출하는 코드를 바꾸지 않고 구현을 서로 교체할 수 있기 때문입니다.
예를 들어 아래의 ITextRenderer 구현 둘 중 어느 것을 넣어도 동작합니다.
interface ITextRenderer {
(text: string, capitalize: boolean): string;
};
var capitalRenderer: ITextRenderer = function (text: string) {
return text.capitalizeCase();
}
var flexibleRenderer: ITextRenderer = function (text: string, capitalize: boolean) {
if (capitalize) {
return text.capitalizeCase();
}
return text.toLowerCase();
}
// Either implementation can go here
//var renderer = capitalRenderer;
var renderer = flexibleRenderer;
renderer("demo", true);
TypeScript가 이를 허용하지 않았다면 capitalRenderer에 본문에서 전혀 사용하지 않는 capitalize 매개변수를 넣어야 해서 함수가 더 읽기 어려워졌을 겁니다.
영어에서 번역·원문 보기The interface requires every caller of an implementing function to provide both mandatory parameters, text and capitalize.
TypeScript knows that JavaScript tolerates receiving extra arguments which go unused, so implementations are permitted to omit them.
What makes that acceptable? It lets you replace one implementation with another without changing the caller.
For instance: Both implementations of ITextRenderer below can be substituted and still work.
interface ITextRenderer {
(text: string, capitalize: boolean): string;
};
var capitalRenderer: ITextRenderer = function (text: string) {
return text.capitalizeCase();
}
var flexibleRenderer: ITextRenderer = function (text: string, capitalize: boolean) {
if (capitalize) {
return text.capitalizeCase();
}
return text.toLowerCase();
}
// Either implementation can go here
//var renderer = capitalRenderer;
var renderer = flexibleRenderer;
renderer("demo", true);
Without this allowance in TypeScript, capitalRenderer would need a capitalize parameter even though its body never uses that parameter at all, making the function harder to read.