🖥️

8. 타입스크립트로의 이주, 마이그레이션


8.1 마이그레이션을 해야 하는 이유

1장에서 살펴본 바와 같이 타입스크립트는 자바스크립트보다 개선된 언어이다. 새로운 프로젝트를 시작한다면 처음부터 타입스크립트로 작성하면 되지만, 이미 자바스크립트로 작성되어 있는 프로젝트는 규모가 매우 클 수 있기 때문에 점진적으로 타입스크립트로 전환하는 과정이 필요하다.
규모가 큰 프로젝트를 타입스크립트로 마이그레이션 하는 과정은 많은 시간을 소모할 수 있으나, 결과적으로 자바스크립트에 타입을 추가해 줌으로써 코드의 퀄리티와 가독성을 높일 수 있고 프로젝트 과정에서 발생할 수 있는 런타임 에러들(예를 들어 동일 연산자의 인수 강제 변환, 존재하지 않는 프로퍼티의 접근 허용 등으로 인한 에러)을 방지할 수 있다. 프로젝트의 유지 및 보수에 많은 이점이 된다.
현재 구글, 마이크로소프트, 메타(구 페이스북)와 같은 회사들은 타입스크립트를 사용하고 있다. 또한, 자바스크립트 개발자를 대상으로 한 ‘2021년 JS 현황’ 설문조사에서 타입스크립트를 사용하고 있는 개발자의 비율이 2016년 21%에서 5년 만에 69%로 상승한 것으로 나타났다.
이를 통해 향후 타입스크립트의 점유율이 지속적으로 상승할 것을 예측할 수 있다. 결과적으로 자바스크립트를 타입스크립트로 변환하는 것은 프로젝트를 장기적으로 관리하는 데 있어 좋은 선택지가 될 것이다.
자바스크립트에서 타입스크립트로의 변환은 다양한 에러를 수반할 수 있다. 이 장에서는 타입스크립트로의 마이그레이션 방법과, 마이그레이션 과정에서 발생할 수 있는 에러들을 해결할 수 있는 방법을 살펴 볼 것이다.
 

8.2 마이그레이션 가이드

8.2.1 디렉토리 설정하기

마이그레이션 가이드 파트에서는 번들러 없이 자바스크립트로 구현한 프로젝트를 마이그레이션 한다고 가정한다.
먼저 초기 프로젝트 폴더의 구조는 아래와 같다.
notion imagenotion image
루트 디렉토리에 기본 문서 파일인 index.html이 있고, src 폴더에 script.js, style.css 파일이 존재한다. 여기서 우리가 타입스크립트로 마이그레이션 할 파일이 바로 script.js다.
 
번들러란? 웹 애플리케이션을 구성하는 리소스나 모듈을 하나로 합쳐주는 도구. 대표적으로 webpack이 있다.
 
컴파일한 파일이 들어갈 폴더 생성
먼저 컴파일한 자바스크립트 파일이 들어갈 ‘dist’ 폴더를 하나 생성해보자. 이 폴더에는 타입스크립트에서 자바스크립트로 컴파일한 파일이 들어간다. 마이그레이션을 진행하는 동안 컴파일된 자바스크립트와 파일이 중복되는 일이 없도록 폴더를 분리하는 것이다.
notion imagenotion image
 

8.2.2 tsconfig.json 생성과 기본 설정

tsconfig.json은 타입스크립트를 자바스크립트로 컴파일할 때 경로와 옵션에 관한 설정 파일이다. 이 파일이 있는 위치가 프로젝트의 루트 디렉토리가 된다. 생성 후 tsc 파일명.ts 명령어를 입력할 때 tsconfig.json 파일에서 설정한 옵션에 따라 컴파일이 진행된다.
 

8.2.2.1 tsconfig.json 파일 생성하기

프로젝트 루트 디렉토리에 tsconfig.json 파일을 생성해 보자. 파일을 직접 생성할 수도 있지만 tsc 명령어를 이용할 수도 있다.
터미널에 아래와 같은 명령어를 입력하면 tsconfig.json 파일이 생성된다.
tsc --init
notion imagenotion image
 

8.2.2.2 tsconfig.json 커스터마이징

tsc 명령어로 생성한 tsconfig.json 파일에는 기본적인 옵션과 주석이 포함되어있다. 필요에 따라 내용을 수정하여 옵션을 커스터마이징 할 수 있다.
타입스크립트에는 다양한 컴파일 옵션이 존재하는데, 이번 목차에서는 그중에서도 기본적으로 많이 사용되는 옵션을 위주로 살펴 볼 것이다.
notion imagenotion image
 
💡
공식 홈페이지의 TSConfig Reference 페이지를 확인하면 각 옵션에 대한 자세한 설명을 확인할 수 있다. https://www.typescriptlang.org/tsconfig
 

8.2.2.3 include 와 exclude

includeexclude컴파일할 대상이나 컴파일에서 제외할 대상을 지정하는 속성이다.
// tsconfig.json { "include": ["./src/**.ts"], "exclude": ["node_modules", "dist"], }
 
include
설명
컴파일하고 싶은 파일 또는 디렉토리의 패턴을 지정한다. 배열에 담아서 여러 개를 지정 할 수 있다.
기본 값
**
여기서 기본 값이란 tsconfig.json 파일에 속성을 작성하지 않은 경우에 디폴트로 적용되는 값을 말한다. 만약 include 속성을 작성하지 않는다면 **를 값으로 가진다.
["./src/**.ts"] 와 같이 작성한다면 tsconfig.json 파일이 있는 위치에서 출발해서 src와 모든 하위 디렉토리에서 .ts 파일을 찾는다는 의미다.
exclude
설명
컴파일 대상에서 제외하고 싶은 파일 또는 디렉토리를 지정한다. 배열에 담아서 여러 개를 지정 할 수 있다.
기본 값
“node_modules”, “bower_components”, “jspm_packages”
["node_modules", "dist"] 와 같이 작성한다면 node_modules 와 dist 디렉토리를 모두 제외한다는 의미다. 예시에서는 각각의 파일이 서로 의존성이 있는 폴더와 이미 컴파일 된 파일이 들어가 있는 폴더를 컴파일 대상에서 제외해주었다.
 
💡
includeexclude 에서 특정 패턴의 경로나 파일명을 지정할 때 Glob 패턴을 사용할 수 있다. - ? : 임의의 한 글자 매칭 - * : 하위 디렉토리를 포함하지 않는 임의의 문자열 매칭 - ** : 하위 디렉토리를 포함한 임의의 문자열 매칭
 

8.2.2.4 compilerOptions

compilerOptionsincludeexclude로 지정한 대상을 컴파일 과정에서 처리할 방법에 대한 속성이다.
// tsconfig.json { "include": ["./src/**.ts"], "exclude": ["node_modules", "dist"], "compilerOptions": { "outDir": "./dist" "target": "ES5", "lib": ["ES5", "DOM"], "module": "commonjs", "allowJS": true, } }
 
outDir
설명
컴파일한 자바스크립트 파일이 생성될 디렉토리를 결정한다.
기본 값
값을 지정하지 않으면 타입스크립트와 동일한 디렉토리에 생성된다.
"outDir": "./dist"로 작성 후 컴파일을 진행하면 dist 폴더에 script.js 파일이 생성된 것을 볼 수 있다.
notion imagenotion image
 
target
설명
컴파일 시 자바스크립트의 ECMAScript 버전을 결정한다.
기본 값
ES3
사용 가능한 값
ES3, ES5, ES6/ES2015, ES2016, ES2017, ES2018, ES2019, ES2020, ES2021, ES2022, ESNEXT
"target" 옵션의 값에 따라 컴파일된 자바스크립트 파일의 문법이 달라진다. 예를 들어 화살표 함수와 const 키워드를 쓴 코드가 있다.
// script.ts const sum = (x: number, y: number) => { return x + y; };
 
"target": "ES6" 인 경우에는 화살표 함수와 const 키워드가 그대로 컴파일 된다.
// script.js const sum = (x, y) => { return x + y; };
 
"target": "ES5" 인 경우, 화살표 함수가 일반 함수로, constvar로 변경되어 컴파일 된다.
// script.js var sum = function (x, y) { return x + y; };
 
lib
설명
컴파일 할 때 포함될 라이브러리의 목록을 결정한다.
기본 값
target 에 따라 다른 기본 값을 가진다. target : ES3 인 경우 ⇒ DOM, ES5, ScriptHost target : ES5 인 경우 ⇒ DOM, ES6, DOM.Iterable, ScriptHost
사용 가능한 값
DOM, ScriptHost, ES5, ES6/ES2015, ES2016, ES2017, ES2018, ES2019, ES2020, ES2021, ESNEXT 등
만약 웹 브라우저에서 동작하는 프로젝트를 진행한다면 DOM API를 가져다 쓸 것이다. 하지만 타입스크립트에서 아래와 같은 코드를 실행한다면 에러가 발생한다. 그 이유는 타입 스크립트는 기본적으로 외부 API의 타입 정보를 가지고 있지 않기 때문이다.
document.write('hello');
 
notion imagenotion image
 
간단하게 lib 옵션을 사용하면 타입스크립트에게 외부 API를 사용할 것이라고 알릴 수 있다. 컴파일 옵션에 "lib": ["DOM"] 을 추가한다면 DOM과 관련된 API가 호출되어 document.write() 와 같은 메서드를 사용할 수 있게 된다.
 
module
설명
컴파일 된 자바스크립트가 사용하게 될 module 방식을 결정한다.
기본 값
CommonJS
사용 가능한 값
NONE, CommonJS, AMD, UMD, SYSTEM, ES6/ES2015, ES2020, ES2022, ESNEXT, NODE16, NODENEXT
프로젝트가 동작할 플랫폼에 따라 그에 맞는 모듈 방식을 선택할 필요가 있다. 예를 들어 ES6 문법으로 컴파일 시 import 문법을 사용하면 import가 그대로 컴파일된다. import 문법은 node 환경에서 실행이 불가능하기 때문에 모듈 옵션을 변경해주어야 하는데, "module": "CommonJS" 를 추가하면 import 를 require 문법으로 컴파일이 가능하다.
 
import example from './example.js'; example();
"module": "CommonJS" 인 경우 위 코드는 아래와 같이 컴파일 된다.
 
notion imagenotion image
 
allowJS
설명
컴파일 시 JS와 JSX 확장자 파일의 허용 여부를 결정한다.
기본 값
false
타입스크립트는 기본적으로 컴파일 시 타입스크립트 파일 외에는 에러가 발생한다.
notion imagenotion image
 
"allowJs : true" 인 경우에는 자바스크립트 파일을 프로젝트에 포함할 수 있다. 이 옵션은 주로 jQuery 같은 자바스크립트 기반 라이브러리를 사용하거나, 점진적으로 마이그레이션을 진행할 때 활용한다.
 
💡
VSCode 에디터에서 jsconfig.json 속성에 마우스 오버를 하면 설명과 함께 공식 사이트 링크를 제공한다.
notion imagenotion image
 

8.2.3 에러 방지

타입스크립트로 파일을 변환하기 전, 앞서 생성한 tsconfig.json 파일에 컴파일 옵션을 추가해 줌으로써 초기 에러를 방지할 수 있다.
타입스크립트에는 다양한 컴파일 옵션이 존재한다. 컴파일 옵션에 대해서는 8.3 마이그레이션 이후 파트에서 더 자세하게 설명되어 있으며, 8.2.3에서는 마이그레이션의 초기 과정에 도움을 줄 수 있는 두 가지 옵션에 대해서 간단하게 살펴 볼 것이다. 다음의 두 가지 옵션을 적용하면 가장 기본적인 에러를 확인하기 편리하다.
함수의 마지막에 return을 빠뜨리는 것을 방지하는 noImplicitReturns와, 타입 추론이 불가능하고 타입 선언이 되지 않은 값이 any로 평가되는 것을 방지하는 noImplicitAny에 대해 알아볼 것이다.
.ts 파일로 변환 후 해당 옵션을 추가하고 에러를 해결해 나가도 무방하며, 지금은 .ts파일로 전환 전 가벼운 설정이라 여기면 된다.
 

8.2.3.1 noImplicitReturns 설정하기

🔷
다음과 같이 tsconfig.json 파일에 "noImplicitReturns": true 값을 추가해 준다.
{ ... "compilerOptions": { "outDir": "./dist" "target": "ES5", "lib": ["ES5", "DOM"], "module": "commonjs", "allowJS": true, "noImplicitReturns": true } }
noImplicitReturns가 활성화되면 함수의 모든 코드 경로를 검사하여 return 값이 빠져있는지 확인한다.
notion imagenotion image
다음과 같은 함수를 선언했다고 가정했을 때, 5번째 줄에 return이 빠져있는 것을 확인할 수 있다. 이와 같은 상황에서 타입스크립트는 다음과 같은 에러를 반환한다.
notion imagenotion image
해당 에러를 해결할 수 있는 방법에 대해서는 8.3 마이그레이션 이후에서 더 자세하게 알아볼 것이다.
 

8.2.3.2 noImplicitAny 설정하기

🔷
다음과 같이 tsconfig.json 파일에 "noImplicitAny": true 값을 추가해 준다.
{ ... "compilerOptions": { "outDir": "./dist" "target": "ES5", "lib": ["ES5", "DOM"], "module": "commonjs", "allowJS": true, "noImplicitReturns": true, "noImplicitAny": true } }
타입스크립트에서는 타입이 명시되지 않았거나 타입추론이 불가능한 값을 any 타입으로 평가한다. noImplicitAny 옵션은 이러한 상황에서 any 타입으로 평가된 값에 대한 에러 반환 여부를 결정한다.
타입스크립트는 해당 옵션을 활성화 시키지 않아도 경고를 나타내긴 하나, 옵션을 활성화 시키면 컴파일 시 에러를 발생시켜 컴파일을 막아 더 안전하게 코드를 작성할 수 있다.
notion imagenotion image
위 형태와 같이 매개변수에 어떤 타입도 정해주지 않았을 때 다음과 같은 에러를 발생시킨다.
notion imagenotion image
해당 에러를 해결할 수 있는 방법에 대해서는 8.3 마이그레이션 이후에서 더 자세하게 알아볼 것이다.
 

8.2.4 TypeScript 파일로 변환하기

8.2.3 까지의 과정이 완료되었다면, 타입스크립트 파일로 변환하기만 하면 된다. .js 파일은 .ts 파일로, .jsx 파일이라면 .tsx로 확장자만 변경해주면 마이그레이션이 완료된다.
🔷
파일의 확장자 명을 변경하는 것으로 마이그레이션은 완료된다.
notion imagenotion image
notion imagenotion image
확장자를 변경한 타입스크립트 파일을 vscode와 같은 에디터로 열어보면 군데군데 발생해 있는 에러들을 확인할 수 있을 것이다. 해당 에러들은 자바스크립트 파일로 작성할 때 에러가 발생하지 않았던 부분들이 타입스크립트에서 엄격한 체킹을 거치며 발생한 에러들이다.
또한 적용되지 않은 컴파일 옵션들을 하나씩 활성화 하였을 때, 새롭게 발생하는 에러들이 있 것이다. 따라서 타입스크립트로 마이그레이션 한 후, tsconfig.json 파일에 컴파일 옵션들을 적용하며 점진적으로 에러를 해결해 나가는 과정이 필요하다.
8.3 마이그레이션 이후파트에서는 해당 에러들을 점진적으로 해결할 수 있는 방안에 대해 살펴 볼 것이다.
 

8.3 마이그레이션 이후

타입스크립트로 확장자 변환을 마친 후 해당 파일에서 나타나는 에러들을 점진적으로 해결해 나가야 한다.
먼저, 8.2.3 에러 방지 파트에서 적용해 주었던 noImplicitAny, noImplicitReturns 옵션으로부터 발생한 에러의 해결 방법부터 알아 볼 것이다. 이후 컴파일 옵션들을 하나씩 적용하며 타입스크립트 코드를 더욱 엄격하게 작성할 수 있다.
 

8.3.1 암묵적 타입 추론 금지! noImplicit

noImplicit 옵션들은 타입이 암묵적으로 평가되는 상황을 방지하는 목적을 가지고 있다. 암묵적으로 평가되는 상황은 개발자의 의도가 반영된 것이 아니기 때문에 예상치 못한 문제를 발생시킬 수 있다. noImplicit 옵션을 활용하면 문제를 사전에 방지하여 더욱 안정성 있는 코드를 작성할 수 있다.

8.3.1.1 noImplicitAny

설명
true
타입이 명시되지 않았거나 타입추론이 불가능한 값을 any 타입으로 사용하는 것을 금지한다.
false (default)
타입이 명시되지 않았거나 타입추론이 불가능한 값을 any 타입으로 사용하는 것을 허용한다.
function sum(a, b) { return a + b; }
"noImplicitAny: true" 인 경우 위 코드에서 에러가 발생한다. 타입스크립트가 sum 함수의 파라미터 a, b 를 any로 암묵적으로 타입 추론하기 때문이다.
notion imagenotion image
 
any로 평가된 값에 타입을 명시함으로써 에러를 해결할 수 있다. 암묵적으로 타입이 추론된 것이 아니라면 타입을 any로 명시하는 것도 가능하다. 그러나 타입스크립트에서 any 타입을 사용하는 것을 지양하고 있으므로 상황에 따라 적절하게 사용하여야 한다.
// 타입을 명시 function sum1(a: number, b: number) { return a + b; } // 타입을 명시 function sum2(a: any, b: any) { return a + b; }
 
자주 발생할 수 있는 상황으로, 변수 선언 후에 값을 할당하지 않은 let 키워드에 대한 에러를 확인할 수 있다.
let count; setTimeout(function () { count++; }, 1000);
notion imagenotion image
 
타입을 명시해주어도 되지만, 타입스크립트가 타입을 추론할 수 있도록 초기 값을 할당해주어도 에러가 해결된다.
// 초기값을 할당 let count = 0; setTimeout(function () { count++; }, 1000); // 타입을 명시 let count: number; setTimeout(function () { count++; }, 1000);
 

8.3.1.2 noImplicitReturns

설명
true
함수가 암묵적으로 undefined를 반환하는 것을 금지한다.
false (default)
함수가 암묵적으로 undefined를 반환하는 것을 허용한다.
function checkEmpty(item): boolean { if (typeof item== 'undefined' || item== null || item== '') { return true; } }
"noImplicitReturns: true" 인 경우 위 코드에서 에러가 발생한다. 함수가 일부 조건에서 암묵적으로 undefined를 반환하기 때문이다. checkEmpty 함수에서 if 문을 만족하는 경우에는 true를 반환하지만, if 문을 만족하지 않는 경우에는 따로 return문을 명시하지 않아서 함수가 암묵적으로 undefined를 반환한다.
notion imagenotion image
 
어떤 조건에서든 함수가 값을 return 할 수 있도록 return문을 명시하면 에러가 해결된다.
function checkEmpty(item): boolean { if (typeof item == 'undefined' || item == null || item == '') { return true; } else { return false; // return문 추가 } }
 

8.3.1.3 noImplicitOverride

설명
true
메서드가 암묵적으로 오버라이딩 되는 것을 금지한다.
false (default)
메서드가 암묵적으로 오버라이딩 되는 것을 허용한다.
noImplicitOverride는 클래스를 사용하는 상황에서 적용되는 옵션이다. 값이 true 일 때 오버라이딩된 메서드에 override 키워드를 적어주지 않으면 에러가 발생한다. 이 옵션을 활용하면 부모 클래스의 메서드를 실수로 오버라이딩 하는 것을 사전에 방지할 수 있으며, override 키워드를 명시함으로써 가독성을 높일 수 있다.
class Person { public name: string; public nickname: string; constructor(name: string, nickname: string) { this.name = name; this.nickname = nickname; } sayHello() { console.log('Hello!'); } get getNickname(): string { return this.nickname; } set setNickname(nickname: string) { this.nickname = nickname; } } class Student extends Person { sayHello() {} get getNickname(): string { return this.nickname; } set setNickname(nickname: string) { this.nickname = nickname; } }
"noImplicitOverride: true" 인 경우 다음과 같은 에러가 발생한다.
notion imagenotion image
 
에러를 해결하기 위해서는 자식 클래스의 오버라이딩된 메서드 앞에 override 키워드를 추가하면 된다. 만약 오버라이딩을 원하지 않는다면 에러가 발생한 메서드의 이름을 부모 클래스의 메서드와 중복되지 않게 바꿔 준다.
class Person { public name: string; public nickname: string; constructor(name: string, nickname: string) { this.name = name; this.nickname = nickname; } sayHello() { console.log(`Hello ${this.name}!`); } get getNickname(): string { return this.nickname; } set setNickname(nickname: string) { this.nickname = nickname; } } class Student extends Person { override sayHello() { console.log(`Hello ${this.name}!`); } override get getNickname(): string { return this.nickname; } override set setNickname(nickname: string) { this.nickname = nickname; } }
 

8.3.1.4 noImplicitThis

설명
true
this 키워드가 암묵적으로 any 타입으로 추론되는 것을 금지한다.
false (default)
this 키워드가 암묵적으로 any 타입으로 추론되는 것을 허용한다.
자바스크립트의 this는 함수가 호출되는 방식에 따라 동적으로 바인딩 된다. 이와 같은 이유로 타입스크립트에서 this의 타입을 추론할 수 없는 상황이 생기는데, noImplicitThis 옵션은 이와 같은 상황에서 암묵적으로 any타입을 추론하는 경우를 방지하는 옵션이다.
"noImplicitThis: true" 인 경우 아래 코드에서 에러가 발생한다. 중첩 함수가 일반 함수로 호출되면 this는 전역 객체를 가리키게 된다. 이 때 클래스 내부에서는 thisundefined를 반환하는데, 타입스크립트가 이를 any로 타입을 추론하면서 에러가 발생한다.
class Person { name: string; constructor(name: string) { this.name = name; } getName() { return function () { return this.name; // this 는 undefined }; } } const user = new Person('Son'); user.getName()();
 
중첩 함수의 this를 전역 객체가 아닌 메서드의 this와 일치시키는 방법은 다음과 같다.
일반 함수 대신 화살표 함수를 사용한다. 화살표 함수의 this는 상위 스코프의 this를 가리키므로 중첩 함수의 this가 메서드의 this와 동일해지면서 에러가 해결된다.
class Person { name: string; constructor(name: string) { this.name = name; } getName() { return () => { // 화살표 함수 return this.name; }; } } const user = new Person('Son'); user.getName()(); // Son
 
다른 방법으로는 this를 변수 that에 할당하여 중첩 함수 내부에서 this 대신 that을 참조하도록 할 수 있다. 중첩 함수의 this 대신 메서드의 this를 참조하면서 에러가 해결된다.
class Person { name: string; constructor(name: string) { this.name = name; } getName() { const that = this; // 변수 that에 this를 할당 return function () { return that.name; }; } } const user = new Person('Son'); user.getName()(); // Son
 

8.3.2 조금 더 엄격하게! strict

strict 옵션들은 타입스크립트의 타입을 더욱 엄격하게 평가하여 프로그램의 정확성을 높여준다. 타입스크립트 팀은 strict 옵션을 strict mode family라고 지칭하고 있으며, 자바스크립트의 use strict와 비슷한 옵션이라고 볼 수 있다. 개발자의 필요에 따라 각각의 strict 옵션을 활성화 할 수 있다. 이 장에서는 alwaysStrictstrictNullCheck에 대해 살펴 볼 것이다.
 

8.3.2.1 alwaysStrict

설명
true
소스 코드에서 strict 룰을 위반한다면 에러를 발생시킨다.
false (default)
소스 코드에서 strict 룰을 위반하더라도 허용한다.
해당 옵션을 활성화 할 경우, 각 소스 파일에 ‘use strict’가 적용되어 있는 것처럼 작동하며 파일을 ECMAScript 엄격 모드(Strict modee)로 분석 하고 strict룰에 위반되는 경우 에러를 발생시킨다.
notion imagenotion image
notion imagenotion image
notion imagenotion image
 

8.3.2.2 strictNullChecks

설명
true
구체적인 값이 필요한 상황에서 값이 null 및 undefined일 경우 에러를 발생시킨다.
false (default)
구체적인 값이 필요한 상황에서 값이 nullundefined인 경우 무시된다.
다음과 같은 타입스크립트 코드를 사용하는 경우, find 메서드는 조건을 만족하는 첫 번째 요소의 값을 반환한다. 혹은 그러한 요소가 없다면 undefined를 반환하도록 되어있으므로 loggedInUserundefined가 될 수 있다.
declare const userName: string; const users = [ { name: "Kim", age: 15 }, { name: "Son", age: 28 }, ]; const loggedInUser = users.find((v) => v.name === userName); console.log(loggedInUser.age); // TypeScript 공식문서
따라서 “strictNullChecks: true” 인 경우 위의 코드를 실행하기 전에 다음과 같은 에러가 발생한다.
notion imagenotion image
 
해당 에러는 다음과 같이 if 문을 활용해서 loggedInUsernull 이나 undefined인지 검사하는 방법을 사용하면 해결된다.
declare const userName: string; const users = [ { name: "Kim", age: 15 }, { name: "Son", age: 28 }, ]; const loggedInUser = users.find((v) => v.name === userName); if (loggedInUser) { // if 문을 활용해 loggedInUser가 true 일 때 작동되도록 함 console.log(loggedInUser.age); } // TypeScript 공식문서
 
다음과 같이 옵셔널 체이닝 연산자?를 사용해도 해결된다.
declare const userName: string; const users = [ { name: "Kim", age: 15 }, { name: "Son", age: 28 }, ]; const loggedInUser = users.find((v) => v.name === userName); console.log(loggedInUser?.age); // 옵셔널 체이닝 연산자 사용 // TypeScript 공식문서
옵셔널 체이닝(optional chaining) 옵셔널 체이닝?.을 사용하면 프로퍼티가 없는 중첩 객체를 에러 없이 안전하게 접근할 수 있습니다. // 모던 JavaScript 튜토리얼
 

8.3.3 안 쓰는 건 없애자! noUnused

Unused 옵션들은 소스 코드에서 사용하지 않거나, 실행될 수 없는 코드가 있을 경우 이를 관리할 방법에 대한 옵션들이다.
 

8.3.3.1 noUnusedLocals

설명
true
사용하지 않는 지역 변수에 대한 에러를 발생시킨다.
false (default)
사용하지 않는 지역 변수가 있더라도 무시한다.
const createUserId = (userId: string) => { const id = 'one'; return { type: "Id", userId }; }; // TypeScript 공식문서
위 코드에서 id가 선언되었으나 사용되지는 않고 있다. 해당 상황과 같이 사용되지 않는 지역변수가 있을 경우 다음과 같은 에러를 발생시킨다.
위 코드에서 id가 선언되었으나 사용되지는 않고 있다. “strictUnusedLocals: true” 인 경우, 코드를 실행하기 전 사용되지 않는 지역변수에 대한 에러가 발생한다.
notion imagenotion image
 
다음과 같이 사용되지 않는 변수를 제거해 주면 에러가 해결된다.
const createUserId = (userId: string) => { return { type: "Id", userId }; };
 

8.3.3.2 noUnusedParameters

설명
true
사용하지 않는 인자에 대한 에러를 발생시킨다.
false (default)
사용하지 않는 인자가 있더라도 무시한다.
const createUserId = (userId: string) => { const id = 'one'; return { type: "Id", userId: id }; }; // TypeScript 공식문서
위 코드에서 userID 인자는 사용되지 않고 있다. 해당 상황과 같이 사용되지 않는 인자(Parameter)가 있을 경우 다음과 같은 에러를 발생시킨다.
notion imagenotion image
 
다음과 같이 인자를 사용해 주면 에러가 해결된다.
const createUserId = (userId: string) => { const id = 'one'; return { type: "Id", userId: userId, id}; }; // TypeScript 공식문서