정적 분석

정적 분석은 코드를 실제로 실행하거나 자동 테스트를 작성할 필요 없이 코드를 자동으로 확인하는 테스트 유형입니다. VSCode와 같은 IDE를 사용하는 경우 이미 이러한 종류의 테스트를 봤을 것입니다. TypeScript에서 실행하는 유형 검사는 일종의 정적 분석이며 오류 또는 경고 아래에 구불구불한 선으로 표시될 수 있습니다.

ESLint

ESLint는 코드베이스에서 발생할 수 있는 문제에 관한 의견을 제공할 수 있는 도구입니다. 이러한 문제는 유형안전성이 뛰어나지만 그 자체로 오류 또는 비표준 동작일 수 있습니다. ESLint를 사용하면 '권장' 세트에 있는 여러 규칙을 포함하여 코드베이스에서 검사되는 여러 규칙을 적용할 수 있습니다.

ESLint 규칙의 좋은 예는 no-unsafe-Finally 규칙입니다. 이렇게 하면 finally 블록 내에서 프로그램의 제어 흐름을 수정하는 문을 작성할 수 없습니다. 이는 따라하기 어려운 JavaScript를 작성하는 특이한 방법이므로 이는 좋은 규칙입니다. 그러나 정상적인 코드 검토 프로세스에서 감지할 수 있어야 합니다.

  try {
    const result = await complexFetchFromNetwork();
    if (!result.ok) {
      throw new Error("failed to fetch");
    }
  } finally {
    // warning - this will 'overrule' the previous exception!
    return false;
  }

따라서 ESLint는 건전한 검토 프로세스 (및 코드베이스의 모양을 정의하는 스타일 가이드)를 대체하지 않습니다. 개발자가 코드베이스에 도입하려고 할 수 있는 모든 비정상적인 접근 방식을 포착하지 않기 때문입니다. Google의 엔지니어링 관행 가이드에 '단순하게 유지하기'에 관한 짧은 섹션이 나와 있습니다.

ESLint를 사용하면 규칙을 깨고 코드에 '허용됨'으로 주석을 달 수 있습니다. 예를 들어 이전 로직을 다음과 같이 주석 처리하여 허용할 수 있습니다.

  finally {
    // eslint-disable-next-line no-unsafe-finally
    return false;
  }

계속해서 규칙을 어기면 규칙을 사용 중지하는 것을 고려해 보세요. 이러한 도구는 특정 방식으로 코드를 작성하도록 유도하지만 팀은 다른 방식으로 코드를 작성하는 데 익숙할 수 있으며 이러한 접근 방식의 위험을 이미 알고 있을 수 있습니다.

마지막으로 대규모 코드베이스에서 정적 분석 도구를 사용 설정하면 다른 방법으로는 제대로 작동하던 코드에 유용하지 않은 노이즈 (및 리팩토링하는 작업)가 많이 발생할 수 있습니다. 따라서 프로젝트 수명 주기 초기에 사용 설정하는 것이 더 쉽습니다.

브라우저 지원을 위한 ESLint 플러그인

광범위하게 지원되지 않거나 대상 브라우저 목록에서 지원되지 않는 API 사용을 플래그하는 플러그인을 ESLint에 추가할 수 있습니다. eslint-plugin-compat 패키지는 사용자가 API를 사용할 수 없을 때 경고를 표시할 수 있으므로, 개발자가 끊임없이 직접 추적할 필요가 없습니다.

정적 분석을 위한 유형 확인

신입 개발자는 자바스크립트를 배울 때 일반적으로 약하게 입력되는 언어라는 사실을 알게 됩니다. 즉, 변수를 하나의 유형으로 선언한 다음 완전히 다른 항목에 동일한 위치를 사용할 수 있습니다. 이는 Python 및 기타 스크립트 언어와 비슷하지만 C/C++, Rust와 같은 컴파일된 언어와는 다릅니다.

이러한 종류의 언어는 시작하는 데 유용할 수 있습니다. 이러한 단순성으로 인해 JavaScript가 널리 사용되기는 하지만, 일부 코드베이스에서는 장애 지점이 되거나 적어도 혼란을 야기하는 오류가 발생할 수 있습니다. 예를 들어 string 또는 객체 유형이 예상되는 경우 number을 전달하면 잘못된 유형이 지정된 값이 여러 라이브러리를 통해 전파된 후 최종적으로 혼란을 야기할 수 있습니다. TypeError.

TypeScript

TypeScript는 JavaScript의 입력 정보 부족에 대한 가장 주류적인 솔루션입니다. 이 과정에서는 이를 광범위하게 사용합니다. TypeScript에 관한 과정은 아니지만 정적 분석을 제공하기 때문에 도구 상자의 중요한 부분이 될 수 있습니다.

간단한 예로, string 이름과 number 나이를 허용하는 콜백이 주어질 것으로 예상되는 다음 코드는 다음과 같습니다.

const callback = (name: string, age: string): void => {
  console.info(name, 'is now', age, 'years old!');
};
onBirthday(callback);

TypeScript를 통해 실행하거나 IDE에서 마우스를 가져갈 때도 다음 오류가 발생합니다.

bad.ts:4:12 - error TS2345: Argument of type '(name: string, age: string) => void' is not assignable to parameter of type '(name: string, age: number) => void'.
  Types of parameters 'age' and 'age' are incompatible.
    Type 'number' is not assignable to type 'string'.

4 onBirthday(callback);
             ~~~~~~~~

Found 1 error in bad.ts:4
팝업에 오류 메시지와 함께 IDE에 표시된 이전 예의 코드
잘못된 유형을 전달했음을 나타내는 VSCode.

궁극적으로 TypeScript 사용의 목표는 이와 같은 오류가 프로젝트에 들어오지 않도록 하는 것입니다. 나이는 string가 아니라 number이어야 합니다. 이러한 종류의 오류는 다른 유형의 테스트를 사용하여 감지하기 어려울 수 있습니다. 또한 유형 시스템은 테스트가 작성되기 전에 피드백을 제공할 수 있습니다. 이렇게 하면 코드가 최종적으로 실행될 때가 아니라 소프트웨어를 개발할 때 유형 오류에 관한 의견을 조기에 제공하여 코드 작성 프로세스가 더 쉬워집니다.

TypeScript를 사용할 때 가장 어려운 부분은 TypeScript를 올바르게 설정하는 것입니다. 모든 프로젝트에는 tsconfig.json 파일이 필요하며 이 파일은 주로 tsc 명령줄 도구 자체에서 사용되지만 VSCode와 같은 IDE에서 Vitest를 비롯한 다른 많은 빌드 도구 및 도구와 함께 읽습니다. 이 파일에는 수백 개의 옵션과 플래그가 포함되어 있으며 다음에서 설정에 유용한 리소스를 찾을 수 있습니다.

일반적인 TypeScript 도움말

tsconfig.json 파일을 통해 TypeScript를 설정하고 사용할 때는 다음 사항에 유의하세요.

  • 소스 파일이 실제로 포함되어 있고 선택되어 있는지 확인합니다. 알 수 없는 이유로 파일에 '오류가 없는' 경우 파일을 검사하지 않았기 때문일 수 있습니다.
  • 함수를 작성할 때 암시적으로 설명하는 대신 .d.ts 파일 내의 유형과 인터페이스를 명시적으로 설명하면 코드베이스를 더 쉽게 테스트할 수 있습니다. 관련된 인터페이스가 명확하면 모의 버전과 '가짜' 버전의 코드를 더 쉽게 작성할 수 있습니다. .

TypeScript 암시적 임의

TypeScript의 가장 강력하고 효과적인 구성 옵션 중 하나는 noImplicitAny 플래그입니다. 하지만 특히 이미 대규모 코드베이스가 있는 경우에는 사용 설정하기가 가장 어려울 수 있습니다. strict 모드인 경우 noImplicitAny 플래그가 기본적으로 사용 설정되지만 그 외의 경우에는 사용 설정되지 않습니다.

이 플래그는 이 함수가 오류를 반환하도록 합니다.

export function fibonacci(n) {
  if (n <= 1) {
    return 0;
  } else if (n === 2) {
    return 1;
  }
  return fibonacci(n - 1) + fibonacci(n - 2);
}

n가 숫자여야 한다는 것은 독자의 입장에서는 분명하지만 TypeScript는 이를 확실하게 확인할 수는 없습니다. VSCode를 사용하는 경우 함수 위로 마우스를 가져가면 다음과 같이 설명이 표시됩니다.

function fibonacci(n: any): any

이 함수의 호출자는 number뿐만 아니라 any 유형(다른 유형을 허용하는 유형)의 값을 전달할 수 있습니다. noImplicitAny 플래그를 사용 설정하면 특정 위치에서 잘못된 데이터 유형을 전달하는 코드에 대해 광범위한 비즈니스 로직 테스트를 작성할 필요 없이 개발 중에 이러한 종류의 코드를 보호할 수 있습니다.

여기서 간단한 해결 방법은 n 인수와 fibonacci의 반환 유형을 모두 number로 표시하는 것입니다.

noImplicitAny 플래그는 코드베이스에 any명시적으로 작성하는 것을 방지하지 않습니다. 여전히 any 유형을 허용하거나 반환하는 함수를 작성할 수 있습니다. 모든 변수에 유형을 부여하는 것뿐입니다.