"this는 일반 인자 목록에는 보이지 않지만, 함수가 안전하게 동작하려면 어떤 수신자가 필요한지 계약에 적을 수 있어."
타입 전용 첫 매개변수
TypeScript에서는 함수의 첫 매개변수 자리에 this: SomeType을 적을 수 있어. 실행 중 전달되는 인자가 아니며 컴파일 결과에서 사라져. 대신 함수 몸 안의 this가 어떤 모양이어야 하는지, 그리고 어느 객체에 붙여 호출할 수 있는지를 타입 검사기에 알려 줘.
function sayName(this: { name: string })은 name 속성이 있는 수신자에서만 안전하게 호출할 수 있어. obj.sayName()처럼 메서드로 부르거나 sayName.call(obj)로 명시해. 평범하게 sayName()이라고 부르면 필요한 this가 없으므로 오류가 난다.
왜 일반 매개변수처럼 세지 않을까
this 매개변수는 타입 층에만 있으므로 함수의 length나 실행 인자 개수에 포함되지 않아. function f(this: X, value: number)의 실행 매개변수는 value 하나야. 라이브러리 선언을 읽을 때 이를 실제 첫 인자로 착각하지 마.
this: void로 의존을 금지해
콜백 타입에 this: void를 적으면 그 함수는 실행 중 this에 의존하면 안 된다는 뜻이야. 누가 어떤 방식으로 호출할지 모르는 콜백 API에서 유용해. 화살표 함수는 실행 중 this를 새로 받지 않으므로 이런 계약을 자연스럽게 만족한다.
반대로 DOM이나 오래된 라이브러리처럼 콜백의 this를 특정 요소로 정해 주는 API라면 정확한 요소 타입을 this 매개변수에 적을 수 있어. 문서에만 있던 호출 관례를 컴파일러가 확인하는 계약으로 옮기는 거야.
메서드에서는 보통 생략해
클래스나 객체의 일반 메서드 안에서는 TypeScript가 둘러싼 객체 타입을 this로 알아내므로 별도 매개변수가 필요하지 않아. 독립 함수, 콜백 시그니처, 호출 가능한 인터페이스처럼 수신자 정보가 선언에서 사라지는 곳에서 주로 사용해.
noImplicitThis가 필요한 이유
this 타입을 적지 않으면 느슨한 설정에서는 this가 any로 빠져 검사가 사라질 수 있어. 엄격 모드의 noImplicitThis는 문맥에서 this 타입을 알 수 없는 자리를 오류로 만들어, 콜백이나 빌려 쓴 메서드의 호출 계약을 명시하게 해.