프로그래밍풀스택 개발자

strictBindCallApply 매개변수가 TypeScript에서 어떻게 작동하며 bind/call/apply 메서드의 타입 안전성을 어떻게 변화시키나요? 모든 세부 사항과 실제 위험을 설명해주세요.

Hintsage AI 어시스턴트로 면접 통과

답변.

질문 배경:

JavaScript는 bind, call 및 apply 메서드를 사용하여 컨텍스트(this)와 인수를 전달할 수 있습니다. TypeScript 3.2가 등장하기 전까지 이러한 메서드는 덜 엄격하게 인식되었으며, 인수에서 불필요한 값이나 잘못된 값을 허용하는 경우가 많아 실행 시 오류가 발생했습니다. TypeScript는 strictBindCallApply 매개변수를 구현하여 이러한 메서드의 시그니처에 대한 엄격한 검사를 추가합니다.

문제:

엄격한 타입 검사가 없었던 경우 bind/call/apply 메서드는 불필요하거나 누락된, 또는 타입이 일치하지 않는 인수를 컴파일 시 오류 없이 "통과"시킬 수 있었습니다.

해결책:

strictBindCallApply가 활성화되면 TypeScript 컴파일러는 엄격하게 요구합니다:

  • 이 메서드에 전달되는 인수는 선언된 메서드 시그니처와 완전히 일치해야 합니다.
  • 불필요하거나 누락되거나 타입이 잘못된 매개변수를 전달할 수 없습니다.
  • this 매개변수는 반드시 컨텍스트의 타입과 일치해야 합니다.

코드 예시:

function sum(a: number, b: number): number { return a + b; } const sum2 = sum.bind(null, 1); sum2(2); // OK sum2(2, 3); // strictBindCallApply에서 오류

주요 특징:

  • 컴파일 단계에서 bind/call/apply를 통한 불필요하거나 잘못된 인수 전달을 제외합니다;
  • 부분 적용 시 this와 함수 매개변수에 대한 지원을 개선합니다;
  • bind/call/apply의 결과가 올바르게 타입화됨을 보장합니다.

트릭 질문.

strictBindCallApply는 오직 함수에만 작동하나요, 아니면 클래스 메서드에도 영향을 미치나요?

함수와 메서드 모두에 영향을 미치며, bind/call/apply 메서드는 모든 함수(Function.prototype)에서 사용할 수 있습니다. 이는 독립 함수 및 클래스 메서드 모두에 해당됩니다.

strictBindCallApply 매개변수를 strict 모드 없이 활성화할 수 있나요?

아니요, 이를 활성화하려면 strict=true 또는 tsconfig.json에서 strictBindCallApply=true를 직접 지정해야 합니다.

bind를 통해 원래 함수에서 정의된 인수보다 더 많은 인수를 전달하면 어떻게 될까요?

strictBindCallApply가 활성화된 TypeScript 컴파일러는 오류를 발생시킵니다: "Expected X arguments, but got Y". 이는 과도한 시그니처 문제나 여분의 변수를 우연히 포착하는 일반적인 오류로부터 보호합니다.

일반적인 오류 및 안티 패턴

  • 함수 오버로드를 모방하기 위해 불필요한 매개변수를 사용하여 bind를 사용하는 것;
  • 매개변수의 불확실한 타입으로 인해 call/apply의 인수 순서가 어긋나는 것;
  • this 타입을 암묵적으로 무시하는 것(특히 화살표 함수를 사용할 때).

실제 사례

** 부정적인 케이스 개발자가 인수를 부분 적용하기 위해 .bind를 사용할 때, 개수에서 오류가 발생합니다. 일반 모드에서는 오류가 없지만, 프로덕션에서 여분의 매개변수로 함수가 호출되어 로직이 깨집니다.

장점:

  • bind/apply를 통한 더 유연한 함수 구현이 가능하여 시그니처에 대해 신경 쓸 필요가 없습니다.

단점:

  • 디버깅이 어려운 함정이 있으며, 프로덕션에서 버그가 발생할 수 있습니다.

** 긍정적인 케이스 strictBindCallApply가 활성화된 경우, 함수와 메서드는 시그니처에 엄격하게 따라 bind를 사용합니다: 불필요하거나 잘못된 인수는 컴파일 단계에서 걸러집니다.

장점:

  • 빌드 시 오류가 나타나고, 코드가 프로덕션에 들어가기 전에 오류를 확인할 수 있습니다;
  • 코드의 신뢰성이 향상되며, 디버그가 훨씬 쉬워집니다.

단점:

  • 기존 코드의 점진적인 "수정"이 필요하며, 때때로 프로젝트의 일부를 리팩토링해야 할 수도 있습니다.