본문으로 건너뛰기

기초

자바스크립트의 모든 값에서는 다양한 동작이 가능하며, 이는 작업을 실행할 때 관찰할 수 있습니다. 추상적으로 들리지만 간단한 예로 message라는 변수에서 실행할 수 있는 몇 가지 작업을 살펴보겠습니다.

js
// message에서 toLowerCase 프로퍼티에 접근하여 호출합니다.
message.toLowerCase();
// message를 호출합니다.
message();
js
// message에서 toLowerCase 프로퍼티에 접근하여 호출합니다.
message.toLowerCase();
// message를 호출합니다.
message();

이를 분석하면 다음과 같습니다. 실행 가능한 첫 번째 코드 줄이 toLowerCase라는 프로퍼티에 접근한 다음 이를 호출합니다. 두 번째 코드 줄은 message를 직접 호출하려고 합니다.

그러나 우리가 message의 값을 모른다고 가정하면(매우 일반적임), 이 코드를 실행할 때 어떤 결과를 얻을 수 있는지 확실하지 않습니다. 각 작업의 동작은 전적으로 처음에 어떤 값을 가지고 있었는지에 따라 달라집니다.

  • message가 호출 가능한가요?
  • 그곳에 toLowerCase라는 프로퍼티가 있나요?
  • 만약 그렇다면 toLowerCase가 호출 가능한가요?
  • 두 값이 모두 호출 가능하다면, 반환되는 값은 무엇인가요?

이러한 질문에 대한 답은 보통 우리가 자바스크립트를 작성할 때 머릿속에 담아두는 내용으로, 모든 세부 사항을 제대로 파악했기를 바랄 수밖에 없습니다.

message가 다음과 같이 정의되었다고 가정해 보겠습니다.

js
const message = "Hello World!";
js
const message = "Hello World!";

예상대로 message.toLowerCase()를 실행하려고 하면 동일한 문자열의 소문자 버전을 얻을 것입니다.

코드의 두 번째 줄은 어떨까요? 자바스크립트에 익숙하다면 다음 예외가 발생하여 실패한다는 것을 알 수 있습니다.

TypeError: message is not a function
TypeError: message is not a function

이런 실수를 피할 수 있다면 정말 좋을 것입니다.

코드를 실행할 때 자바스크립트 런타임이 수행할 작업을 선택하는 방식은, 값의 타입을 파악하는 것(어떤 종류의 동작과 기능이 있는지)입니다. 문자열 "Hello World!"는 함수로 호출될 수 없다는 것이 TypeError가 암시하는 바입니다.

원시값 stringnumber와 같은 일부 값들은 typeof 연산자를 사용하여 런타임에 타입을 식별할 수 있습니다. 그러나 함수를 비롯한 다른 것들은 타입을 식별하는 런타임 수단이 없습니다. 예를 들어 다음 함수를 살펴보겠습니다.

js
function fn(x) {
return x.flip();
}
js
function fn(x) {
return x.flip();
}

호출 가능한 flip 프로퍼티가 있는 객체가 제공된 경우에만 이 함수가 작동한다는 것을, 코드를 읽으면 관찰할 수 있습니다. 하지만 자바스크립트는 이 정보를 코드를 실행할 때 확인할 수 있는 방식으로 표면화하지 않습니다. 순수 자바스크립트에서 fn이 특정 값으로 수행하는 작업을 알려주는 유일한 방법은, 해당 값을 호출하고 어떤 일이 발생하는지 확인하는 것입니다. 이는 코드가 실행되기 전에 코드가 무엇을 할지 예측하기 어렵게 만듭니다. 즉, 코드를 작성하는 동안 코드가 무엇을 할지 파악하기가 어렵습니다.

이렇게 볼 때, 타입fn에 전달할 수 있는 값과, 충돌할 값을 묘사하는 개념입니다. 자바스크립트는 실제로 동적 타이핑만 제공합니다. 즉, 코드를 실행하여 무슨 일이 일어나는지 확인합니다.

대안은 정적 타입 시스템을 사용하여, 코드를 실행하기 전에 어떤 코드가 예상되는지 예측하는 것입니다.

정적 타입 검사

이전에 string을 함수로 호출하려고 했을 때 발생한 TypeError를 다시 생각해 보겠습니다. 대부분의 사람들은 코드를 실행할 때 발생하는 오류를 싫어합니다. 이러한 오류는 버그로 간주됩니다! 그리고 새 코드를 작성할 때 새 버그가 발생하지 않도록 최선을 다합니다.

약간의 코드만 추가하고, 파일을 저장하고, 코드를 다시 실행하고, 즉시 오류를 확인하면 문제를 신속하게 격리할 수 있습니다. 하지만 항상 그럴 수 있는 것은 아닙니다. 기능을 충분히 테스트하지 않아서 실제로 발생할 수 있는 오류를 발견하지 못할 수도 있습니다! 또는 운이 좋게 오류를 발견한다면, 우리는 결국 대규모 리팩터링을 수행하게 됩니다. 그리고 추가된 많은 코드를 다시 파헤쳐야 할 것입니다.

이상적으로는 코드를 실행하기 전에 이러한 버그를 찾는 데 도움이 되는 도구를 사용할 수 있습니다. 바로 이것이 타입스크립트와 같은 정적 타입 검사기가 하는 일입니다. 정적 타입 시스템은 프로그램을 실행할 때의 값의 형태와 동작을 묘사합니다. 타입스크립트와 같은 타입 검사기는 해당 정보를 사용하여 문제가 발생할 수 있는 시점을 알려줍니다.

ts
const message = "hello!";
 
message();
This expression is not callable. Type 'String' has no call signatures.2349This expression is not callable. Type 'String' has no call signatures.
ts
const message = "hello!";
 
message();
This expression is not callable. Type 'String' has no call signatures.2349This expression is not callable. Type 'String' has no call signatures.

마지막 예시를 타입스크립트로 실행하면 코드를 실행하기 전에 오류 메시지가 표시됩니다.

예외가 아닌 실패

지금까지 우리는 런타임 오류와 같은 특정한 것들에 대해 논의했습니다. 즉, 자바스크립트 런타임이 무언가 말이 안 된다고 판단하는 경우입니다. 이러한 오류가 발생하는 이유는, ECMA스크립트 명세서에 예기치 않은 상황이 발생했을 때 언어가 어떻게 작동해야 하는지 명시적인 지침이 있기 때문입니다.

예를 들어 명세서에 따르면, 호출할 수 없는 것을 호출하려고 하면 오류가 발생해야 합니다. 이는 명백해 보입니다. 하지만 여러분은 객체의 존재하지 않는 프로퍼티에 접근하면 오류가 발생해야 한다고도 생각할 수 있습니다. 대신 기대와 다르게 자바스크립트는 undefined 값을 반환합니다.

js
const user = {
name: "Daniel",
age: 26,
};
user.location; // undefined를 반환합니다.
js
const user = {
name: "Daniel",
age: 26,
};
user.location; // undefined를 반환합니다.

궁극적으로 정적 타입 시스템은 어떤 코드를 오류로 표시해야 하는지 판단해야 합니다. 해당 코드가 즉시 오류를 발생시키지 않는 유효한 자바스크립트일지라도 말입니다. 타입스크립트에서 다음 코드는 location이 정의되지 않았다는 오류를 생성합니다.

ts
const user = {
name: "Daniel",
age: 26,
};
 
user.location;
Property 'location' does not exist on type '{ name: string; age: number; }'.2339Property 'location' does not exist on type '{ name: string; age: number; }'.
ts
const user = {
name: "Daniel",
age: 26,
};
 
user.location;
Property 'location' does not exist on type '{ name: string; age: number; }'.2339Property 'location' does not exist on type '{ name: string; age: number; }'.

때때로 이는 표현의 제한을 의미하지만, 그 의도는 프로그램에서 합법적인 버그를 잡기 위한 것입니다. 그리고 타입스크립트는 합법적인 버그를 많이 잡아냅니다.

그 예로는 다음이 있습니다.

오타

ts
const announcement = "Hello World!";
 
// 오타를 얼마나 빨리 발견할 수 있나요?
announcement.toLocaleLowercase();
announcement.toLocalLowerCase();
 
// 아마도 이걸을 작성하려고 했을 것입니다...
announcement.toLocaleLowerCase();
ts
const announcement = "Hello World!";
 
// 오타를 얼마나 빨리 발견할 수 있나요?
announcement.toLocaleLowercase();
announcement.toLocalLowerCase();
 
// 아마도 이걸을 작성하려고 했을 것입니다...
announcement.toLocaleLowerCase();

호출되지 않은 함수

ts
function flipCoin() {
// 원래 의도는 'Math.random()'이었습니다.
return Math.random < 0.5;
Operator '<' cannot be applied to types '() => number' and 'number'.2365Operator '<' cannot be applied to types '() => number' and 'number'.
}
ts
function flipCoin() {
// 원래 의도는 'Math.random()'이었습니다.
return Math.random < 0.5;
Operator '<' cannot be applied to types '() => number' and 'number'.2365Operator '<' cannot be applied to types '() => number' and 'number'.
}

기본적인 논리 오류

ts
const value = Math.random() < 0.5 ? "a" : "b";
if (value !== "a") {
// ...
} else if (value === "b") {
This comparison appears to be unintentional because the types '"a"' and '"b"' have no overlap.2367This comparison appears to be unintentional because the types '"a"' and '"b"' have no overlap.
// 이런, 도달할 수 없습니다.
}
ts
const value = Math.random() < 0.5 ? "a" : "b";
if (value !== "a") {
// ...
} else if (value === "b") {
This comparison appears to be unintentional because the types '"a"' and '"b"' have no overlap.2367This comparison appears to be unintentional because the types '"a"' and '"b"' have no overlap.
// 이런, 도달할 수 없습니다.
}

도구를 위한 타입

타입스크립트는 코드에 실수가 있을 때 버그를 잡아낼 수 있습니다. 훌륭하지만, 타입스크립트는 또한 이러한 실수를 처음부터 방지할 수 있습니다.

타입 검사기에는 변수 및 기타 프로퍼티에서 올바른 프로퍼티에 접근하고 있는지 확인할 수 있는 정보가 있습니다. 해당 정보가 있으면, 사용할 프로퍼티를 제안할 수도 있습니다.

즉, 타입스크립트를 코드 편집에도 활용할 수 있습니다. 핵심 타입 검사기는 편집기에 입력할 때 오류 메시지와 코드 완성을 제공할 수 있습니다. 이것은 사람들이 타입스크립트의 도구에 대해 이야기할 때 자주 언급하는 부분입니다.

ts
import express from "express";
const app = express();
 
app.get("/", function (req, res) {
// 코드 완성이 제공됩니다.
res.sen
         
});
 
app.listen(3000);
ts
import express from "express";
const app = express();
 
app.get("/", function (req, res) {
// 코드 완성이 제공됩니다.
res.sen
         
});
 
app.listen(3000);

타입스크립트는 도구 지원을 중요하게 생각하며 입력할 때의 코드 완성과 오류 제공, 그 이상을 지원합니다. 타입스크립트를 지원하는 편집기는 자동으로 오류를 수정하는 빠른 수정, 코드를 쉽게 재구성하는 리팩터링, 변수 정의로 이동하기, 지정된 변수에 대한 모든 참조를 찾는 유용한 탐색 기능을 제공할 수 있습니다. 이 모든 것은 타입 검사기 위에 구축되었으며 완전한 크로스 플랫폼이므로, 여러분이 선호하는 편집기에서 타입스크립트 지원을 사용할 수 있습니다.

타입스크립트 컴파일러, tsc

우리는 지금까지 타입 검사에 대해 이야기했지만, 아직 타입 검사기를 사용하지는 않았습니다. 우리의 새로운 친구인 타입스크립트 컴파일러, tsc에 대해 알아보겠습니다. 먼저 npm을 통해 가져와야 합니다.

shell
npm install -g typescript
shell
npm install -g typescript
참고

이렇게 하면 타입스크립트 컴파일러, tsc가 전역으로 설치됩니다. 대신 지역 node_modules 패키지에서 tsc를 실행하려면, npx나 유사한 도구를 사용할 수 있습니다.

이제 빈 폴더로 이동하여 첫 번째 타입스크립트 프로그램인 hello.ts를 작성해 보겠습니다.

ts
// 세상에 인사를 건넵니다.
console.log("Hello world!");
ts
// 세상에 인사를 건넵니다.
console.log("Hello world!");

여기에는 다른 점이 없습니다. 이 'hello world' 프로그램은 자바스크립트에서 'hello world' 프로그램을 작성하는 것과 동일하게 보입니다. 이제 typescript 패키지에서 설치한 tsc 명령을 실행하여 타입을 확인해 보겠습니다.

shell
tsc hello.ts
shell
tsc hello.ts

짜잔!

잠깐만요, 뭐가 짜잔이라는 걸까요? tsc를 실행했는데 아무 일도 일어나지 않았습니다! 타입 오류가 없어서 보고할 내용이 없었기 때문에 콘솔에 어떤 출력도 표시되지 않았습니다.

그러나 다시 확인해 보세요. 우리는 대신 어떤 파일 출력을 받았습니다. 현재 디렉터리를 보면 hello.ts 옆에 hello.js 파일이 있다는 것을 확인할 수 있습니다. tschello.ts 파일을 컴파일 또는 변환을 해서 일반 자바스크립트 파일로 출력한 것입니다. 그리고 그 내용물을 보면 타입스크립트가 .ts 파일을 처리한 후에 출력한 내용을 확인할 수 있습니다.

js
// 세상에 인사를 건넵니다.
console.log("Hello world!");
js
// 세상에 인사를 건넵니다.
console.log("Hello world!");

이 경우에는 타입스크립트가 변환할 부분이 거의 없었기 때문에 우리가 작성했던 코드와 동일하게 보입니다. 컴파일러는 사람이 작성한 것 같은 깨끗하고 읽기 쉬운 코드를 생성하려고 합니다. 항상 쉬운 것은 아니지만 타입스크립트는 일관되게 들여쓰기를 하고, 코드가 여러 줄에 걸쳐 있는 경우를 염두에 두고, 주석을 유지하려고 노력합니다.

만약 타입 검사에서 오류가 발생했다면 어떻게 될까요? hello.ts를 다시 작성해 보겠습니다.

ts
// 이것은 산업 등급의 범용 인사 함수입니다.
function greet(person, date) {
console.log(`Hello ${person}, today is ${date}!`);
}
 
greet("Brendan");
ts
// 이것은 산업 등급의 범용 인사 함수입니다.
function greet(person, date) {
console.log(`Hello ${person}, today is ${date}!`);
}
 
greet("Brendan");

tsc hello.ts를 다시 실행하면 명령줄에 오류가 발생합니다!

Expected 2 arguments, but got 1.
Expected 2 arguments, but got 1.

타입스크립트는 우리가 greet 함수에 인수를 전달하는 것을 잊었다고 말하고 있으며, 이는 당연합니다. 지금까지 우리는 표준 자바스크립트만 작성했지만, 타입 검사는 코드에서 문제를 찾을 수 있었습니다. 고마워, 타입스크립트!

오류와 함께 내보내기

마지막 예시에서 눈치채지 못한 한 가지는 hello.js 파일이 다시 변경되었다는 것입니다. 해당 파일을 열면 내용이 여전히 기본적으로 입력 파일과 동일하다는 것을 확인할 수 있습니다. tsc가 코드에 대한 오류를 보고했다는 사실을 고려하면 이는 다소 의외일 수 있습니다. 하지만 이는 타입스크립트의 핵심 가치에 기반합니다. 대부분의 경우, 여러분이 타입스크립트보다 더 잘 안다는 원칙입니다.

앞서 언급한 바와 같이, 타입 검사 코드는 실행할 수 있는 프로그램의 종류를 제한하므로 타입 검사기가 수용할 수 있다고 판단하는 종류에 대한 절충이 있습니다. 대부분의 경우에는 괜찮지만, 이러한 검사가 방해가 되는 시나리오가 있습니다. 예를 들어 자바스크립트 코드를 타입스크립트로 마이그레이션할 때, 타입 검사 오류가 발생한다고 상상해 보겠습니다. 결국에는 타입 검사기를 위해 정리를 하게 되겠지만, 기존의 자바스크립트 코드는 이미 문제없이 작동하고 있었습니다! 타입스크립트로 변환한다고 실행이 중지될 이유가 있을까요?

따라서 타입스크립트는 여러분을 방해하지 않습니다. 물론 시간이 지남에 따라 실수에 대해 좀 더 방어적인 태도를 취하고 타입스크립트가 좀 더 엄격하게 작동하도록 만들 수 있습니다. 이 경우 noEmitOnError 컴파일러 옵션을 사용할 수 있습니다. hello.ts 파일을 변경하고 해당 플래그와 함께 tsc를 실행해 보세요.

shell
tsc --noEmitOnError hello.ts
shell
tsc --noEmitOnError hello.ts

hello.js가 절대 갱신되지 않는다는 것을 확인할 수 있습니다.

명시적 타입

지금까지 우리는 타입스크립트에게 person이나 date가 무엇인지 말하지 않았습니다. 코드를 편집하여 타입스크립트에게 personstring이고 dateDate 객체여야 한다고 알려 주겠습니다. 또한 datetoDateString() 메서드를 사용하겠습니다.

ts
function greet(person: string, date: Date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
ts
function greet(person: string, date: Date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}

persondate타입 주석을 추가하여 greet를 어떤 타입의 값으로 호출할 수 있을지 묘사했습니다. 이 시그니처를 다음과 같이 읽을 수 있습니다. 'greetstring 타입의 personDate 타입의 date를 받는다.'

이제 타입스크립트는 greet가 잘못 호출될 때, 이를 알려줄 수 있습니다. 예를 들면 다음과 같습니다.

ts
function greet(person: string, date: Date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
 
greet("Maddison", Date());
Argument of type 'string' is not assignable to parameter of type 'Date'.2345Argument of type 'string' is not assignable to parameter of type 'Date'.
ts
function greet(person: string, date: Date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
 
greet("Maddison", Date());
Argument of type 'string' is not assignable to parameter of type 'Date'.2345Argument of type 'string' is not assignable to parameter of type 'Date'.

타입스크립트는 두 번째 인수에 대한 오류를 보고했습니다. 그 이유는 무엇일까요?

놀랍게도 자바스크립트에서 Date()를 호출하면 string이 반환됩니다. 반면에 new Date()Date를 생성하면, 우리가 실제로 기대했던 것을 얻을 수 있습니다.

어쨌든 우리는 오류를 신속하게 해결할 수 있습니다.

ts
function greet(person: string, date: Date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
 
greet("Maddison", new Date());
ts
function greet(person: string, date: Date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
 
greet("Maddison", new Date());

명시적인 타입 주석을 항상 작성할 필요는 없다는 점을 기억하세요. 대부분의 경우 타입스크립트는 우리가 타입을 생략하더라도 추론할(알아낼) 수 있습니다.

ts
let msg = "hello there!";
let msg: string
ts
let msg = "hello there!";
let msg: string

msgstring 타입이 있다고 타입스크립트에 알려 주지 않았지만, 타입스크립트는 이를 알아낼 수 있습니다. 이는 타입스크립트의 기능으로, 타입 시스템이 어쨌든 동일한 타입을 추론하게 된다면 주석을 추가하지 않는 것이 가장 좋습니다.

참고

코드 예시의 주석은 마우스를 단어 위에 올렸을 때 편집기에 표시되는 내용입니다.

지워지는 타입

위의 함수 greettsc로 컴파일하여 자바스크립트를 출력할 때 어떤 일이 발생하는지 살펴보겠습니다.

ts
"use strict";
function greet(person, date) {
console.log("Hello ".concat(person, ", today is ").concat(date.toDateString(), "!"));
}
greet("Maddison", new Date());
 
ts
"use strict";
function greet(person, date) {
console.log("Hello ".concat(person, ", today is ").concat(date.toDateString(), "!"));
}
greet("Maddison", new Date());
 

여기서 다음 두 가지 사항에 주목하세요.

  1. persondate 매개변수에는 더 이상 타입 주석이 없습니다.
  2. 백틱(`)을 사용하는 문자열인 템플릿 문자열은 연결(concat)이 있는 일반 문자열로 변환되었습니다.

두 번째 사항에 대해서는 나중에 자세히 다룰 것입니다. 이제 첫 번째 사항에 집중해 보겠습니다. 타입 주석은 자바스크립트(또는 현학적 표현으로는 ECMA스크립트)의 일부가 아니므로 타입스크립트를 수정하지 않고 실행할 수 있는 브라우저나 다른 런타임은 없습니다. 이것이 바로 타입스크립트에 컴파일러가 필요한 이유입니다. 실행할 수 있도록 타입스크립트 관련 코드를 제거하거나 변환하는 방법이 필요합니다. 대부분의 타입스크립트 전용 코드는 지워지는데, 여기서도 마찬가지로 타입 주석이 완전히 지워집니다.

기억

타입 주석은 프로그램의 런타임 동작을 변경하지 않습니다.

하향 조정

위에서 언급했던 또 다른 차이점은 템플릿 문자열이 다음에서

js
`Hello ${person}, today is ${date.toDateString()}!`;
js
`Hello ${person}, today is ${date.toDateString()}!`;

다음으로 다시 작성되었다는 것입니다.

js
"Hello ".concat(person, ", today is ").concat(date.toDateString(), "!");
js
"Hello ".concat(person, ", today is ").concat(date.toDateString(), "!");

왜 이런 일이 생긴 걸까요?

템플릿 문자열은 ECMA스크립트 2015(ECMA스크립트 6, ES2015, ES6 등)라는 ECMA스크립트 버전의 기능입니다. 타입스크립트는 ECMA스크립트의 새로운 버전에서 ECMA스크립트 3이나 ECMA스크립트 5(ES3과 ES5)와 같은 오래된 버전으로 코드를 다시 작성하는 기능을 가지고 있습니다. ECMA스크립트의 최신 또는 상위 버전에서 이전 또는 하위 버전으로 이동하는 과정을 하향 조정(downleveling)이라고 부르기도 합니다.

기본적으로 타입스크립트는 ECMA스크립트의 매우 오래된 버전인 ES3를 대상으로 합니다. target 옵션을 사용하여 조금 더 최근의 것을 선택할 수 있습니다. --target es2015로 실행하면 타입스크립트의 대상이 ECMA스크립트 2015로 변경됩니다. 즉, ECMA스크립트 2015가 지원되는 모든 곳에서 코드를 실행할 수 있어야 합니다. 따라서 tsc --target es2015 hello.ts를 실행하면 다음과 같은 출력이 제공됩니다.

js
function greet(person, date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
greet("Maddison", new Date());
js
function greet(person, date) {
console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}
greet("Maddison", new Date());
참고

기본 대상은 ES3이지만 현재 대부분의 브라우저는 ES2015를 지원합니다. 따라서 특정한 구형 브라우저와의 호환성이 중요한 경우가 아니라면, 대부분의 개발자는 ES2015 이상을 대상으로 안전하게 지정할 수 있습니다.

엄격도

타입스크립트를 사용하는 사람마다 타입 검사기에서 원하는 것이 다릅니다. 어떤 사람들은 프로그램의 일부만 검증하며 느슨한 옵트인 환경을 원합니다. 이는 타입스크립트의 기본 환경입니다. 타입은 선택 사항이고, 추론은 가장 관대한 타입을 사용하고, 잠재적으로 nullundefined 값을 확인하지 않습니다. 오류가 발생했을 때 tsc가 내보내는 방식과 마찬가지로, 기본값은 개발자를 방해하지 않도록 설정되어 있습니다. 기존의 자바스크립트를 마이그레이션하는 경우, 이것이 바람직한 첫 번째 단계일 수 있습니다.

이와는 대조적으로, 많은 사용자는 타입스크립트가 가능한 빨리 유효성을 검사하는 것을 선호합니다. 따라서 언어에서는 엄격도 설정을 제공합니다. 이러한 엄격도 설정은 정적 타입 검사를 스위치(코드가 검사되는지 여부)에서 다이얼에 가까운 것으로 바꿉니다. 이 다이얼을 위로 돌릴수록 타입스크립트가 더 많이 검사합니다. 이를 위해서는 약간의 추가 작업이 필요할 수 있지만, 일반적으로 장기적으로 보면 비용이 많이 들고 더 철저한 검사와 더 정확한 사용이 가능합니다. 가능하면 새 코드베이스는 항상 이 엄격도 검사를 켜야 합니다.

타입스크립트에는 켜거나 끌 수 있는 몇 가지 타입 검사 엄격도 플래그가 있으며, 모든 예시는 별도의 설명이 없는 한 모두 활성화된 상태로 작성됩니다. CLI의 strict 플래그 또는 tsconfig.json"strict": true는 모든 항목을 동시에 토글하지만, 개별적으로 옵트아웃할 수도 있습니다. 가장 중요한 두 가지는 noImplicitAnystrictNullChecks입니다.

noImplicitAny

어떤 곳에서는 타입스크립트가 타입을 추론하려고 하지 않고, 대신 가장 관대한 타입인 any로 되돌아간다는 점을 기억하세요. 결국 any로 되돌아가는 것은 어차피 평범한 자바스크립트 경험일 뿐이니 최악의 상황이 아닙니다.

그러나 any를 사용하면 애초에 타입스크립트를 사용하는 목적에 어긋나는 경우가 많습니다. 프로그램에 타입이 많아질수록 더 많은 유효성 검사와 도구를 얻을 수 있으므로, 코딩에서 더 적은 버그가 발생하게 됩니다. noImplicitAny 플래그를 켜면 타입이 암시적으로 any로 추론되는 모든 변수에서 오류가 발생합니다.

strictNullChecks

기본적으로 nullundefined와 같은 값은 다른 모든 타입에 할당 가능합니다. 이렇게 하면 일부 코드를 더 쉽게 작성할 수 있지만, nullundefined를 처리하는 것을 잊는 것은 세상의 수많은 버그의 원인이 됩니다. 일부는 이를 수십억 달러짜리 실수라고 생각합니다! strictNullChecks 플래그를 사용하면 nullundefined를 보다 명확하게 처리할 수 있으며, nullundefined를 처리하는 것을 잊어버리지 않았는지 걱정할 필요가 없어집니다.