TypeScript Basic

2023.09.12

이웅재 | 엔에이치엔 두레이 프론트엔드개발팀

1. Hello TypeScript !

1-1) TypeScript 란 무엇인가?

1-2) TypeScript 설치 및 사용

1-3) VS Code 설치 밀 설정

1-4) First Type Annotation

TypeScript 란 무엇인가?

Typed JavaScript at any Scale

  • TypeScript extends JavaScript by adding types.

  • By understanding JavaScript,
    TypeScript saves you time catching errors and providing fixes before you run code.

  • Any browser, any OS, anywhere JavaScript runs.
    Entirely Open Source.

TypeScript

= Language

= Typed Superset of JavaScript

= compiles to plain JavaScript

  • 타입스크립트는 ' Programming Language 언어 ' 입니다.

  • 타입스크립트는 ' Compiled Language ' 입니다.

    • 전통적인 Compiled Language 와는 다른 점이 많습니다.

    • 그래서 ' Transpile ' 이라는 용어를 사용하기도 합니다.

  • 자바스크립트는 ' Interpreted Language ' 입니다.

Compiled

  • 컴파일이 필요 O

  • 컴파일러가 필요 O

  • 컴파일하는 시점 O

    • => 컴파일 타임

  • 컴파일된 결과물을 실행

  • 컴파일된 결과물을 실행하는 시점

Interpreted

  • 컴파일이 필요 X 

  • 컴파일러가 필요 X

  • 컴파일하는 시점 X

  • 코드 자체를 실행

  • 코드를 실행하는 시점 o

    • = 런타임

Editor

Browser, Node.js

TypeScript
Compiler

TypeScript 설치 및 사용

Editor

Browser, Node.js

TypeScript
Compiler

자바스크립트 실행 환경 설치

node.js

Chrome's

V8 JavaScript Engine

을 사용하여,

자바스크립트를 해석하고

OS 레벨에서의 API를 제공하는

서버사이드 용

자바스크립트 런타임 환경

browser

HTML 을 동적으로 만들기 위해

브라우저에서

자바스크립트를 해석하고,

DOM 을 제어할 수 있도록 하는

자바스크립트 런타임 환경

node.js 설치

browser 설치

  • 있는거 쓰시면 됩니다.

  • 그래도 크롬이 좀... 낫겠죠 ?

타입스크립트 컴파일러 설치

npm / Visual Studio plugin

  • npm

    • npm i typescript -g

    • node_modules/.bin/tsc

    • tsc source.ts

  • Visual Studio plugin 설치

    • Visual Studio 2017 / 2015 Update 3 이후로는 디폴트로 설치되어 있음

    • 아니면 설치

간단한 컴파일러 사용 예제

  • 타입스크립트 컴파일러를 글로벌로 설치 후,

    • cli 명령어로 파일 컴파일

    • 특정 프로젝트 폴더에서 타입스크립트 컴파일러 설정에 맞춰 컴파일

    • 특정 프로젝트 폴더에서 타입스크립트 컴파일러 설정에 맞춰 컴파일 (watch 모드)

  • 프로젝트에 타입스크립트 컴파일러를 설치 후,

    • .bin 안의 명령어로 파일 컴파일

    • npm 스크립트로 파일 컴파일

    • 프로젝트에 있는 타입스크립트 설정에 맞춰, npm 스크립트로 컴파일

    • 프로젝트에 있는 타입스크립트 설정에 맞춰, npm 스크립트로 컴파일 (watch 모드)

npm i typescript -g
tsc test.ts
tsc --init
tsc
npm uninstall typescript -g

VS Code 설치 및 설정

Visual Studio Code

  • TypeScript Compiler

    • VS Code 에 컴파일러가 내장되어 있다.

    • 내장된 컴파일러 버전은 VS Code 가 업데이트 되면서 올라간다.

      • 그래서 컴파일러 버전과 VS Code 의 버전은 상관 관계가 있다.

    • 내장된 컴파일러를 선택할수 있고, 직접 설치한 컴파일러를 선택할 수도 있다.

Visual Studio Code

First Type Annotation

2. Basic Types

2-1) TypeScript Types vs JavaScript Types    2-2) Primitive Types

2-3) boolean    2-4) number

2-5) string    2-6) symbol

2-7) null & undefined    2-8) object

2-9) Array    2-10) Tuple

2-11) any    2-12) unknown

2-13) never    2-14) void

TypeScript Types

vs

JavaScript Types

Static Types

set during development

vs

Dynamic Types

resolved at runtime

// JavaScript
function add(n1, n2) {
  if (typeof n1 !== 'number' || typeof n2 !== 'number') {
    throw new Error('Incorrect input!');
  }
  return n1 + n2;
}

const result = add(39, 28);

// TypeScript
function add(n1: number, n2: number) {
  return n1 + n2;
}

const result = add(39, 28);
  • For programs to be useful, we need to be able to work with some of the simplest units of data: numbers, strings, structures, boolean values, and the like.
    프로그램이 유용하려면, 가장 간단한 데이터 단위로 작업 할 수 있어야합니다. : numbers, strings, structures, boolean 값 등등

  • In TypeScript, we support the same types as you would expect in JavaScript, with an extra enumeration type thrown in to help things along.
    TypeScript 에서, 우리는 JavaScript 에서 기대하는 것과 동일한 타입을 지원하며, 돕기 위해 추가적인 열거 타입이 제공되었습니다.

  • TypeScript 에서 프로그램 작성을 위해 기본 제공하는 데이터 타입

  • 사용자가 만든 타입은 결국은 이 기본 자료형들로 쪼개집니다.

  • JavaScript 기본 자료형을 포함 (superset)

    • ECMAScript 표준에 따른 기본 자료형은 6가지

      • Boolean

      • Number

      • String

      • Null

      • Undefined

      • Symbol (ECMAScript 6 에 추가)

      • Array : object 형

  • 프로그래밍을 도울 몇가지 타입이 더 제공된다.

    • Any, Void, Never, Unknown

    • Enum

    • Tuple : object 형

Primitive Types

Primitive Type

  • 오브젝트와 레퍼런스 형태가 아닌 실제 값을 저장하는 자료형입니다.

  • 프리미티브 형의 내장 함수를 사용 가능한것은 자바스크립트 처리 방식 덕분

  • (ES2015 기준) 6가지

    • boolean

    • number

    • string

    • symbol (ES2015)

    • null

    • undefined

let name = 'mark';
name.toString();

Primitive Type

  • literal 값으로 Primitive 타입의 서브 타입을 나타낼 수 있다.

true;

'hello';

3.14;

null;

undefined;

Primitive Type

  • 또는 래퍼 객체로 만들 수 있다.

new Boolean(false); // typeof new Boolean(false) : 'object'

new String('world'); // typeof new String('world') : 'object'

new Number(42); // typeof new Number(42) : 'object'

boolean

Boolean / boolean

  • 가장 기본적인 데이터 타입

  • 단순한 true 혹은 false 값 입니다.

  • JavaScript / TypeScript 에서 'boolean' 이라고 부른다.

let isDone: boolean = false;

typeof isDone === 'boolean' // true

// Type 'boolean' is assignable to type 'Boolean'.
let isOk: Boolean = true;

// Type 'Boolean' is not assignable to type 'boolean'.
// 'boolean' is a primitive, but 'Boolean' is a wrapper object.
// Prefer using 'boolean' when possible.
let isNotOk: boolean = new Boolean(true);

number

Number / number

  • JavaScript 와 같이, TypeScript 의 모든 숫자는 부동 소수점 값 입니다.

  • TypeScript는 16진수 및 10진수 리터럴 외에도,
    ECMAScript 2015에 도입된 2진수 및 8진수를 지원합니다.

  • NaN

  • 1_000_000 과 같은 표기 가능

let decimal: number = 6; // 10진수 리터럴

let hex: number = 0xf00d; // 16진수 리터럴

let binary: number = 0b1010; // 2진수 리터럴

let octal: number = 0o744; // 8진수 리터럴

let NotANumber: number = NaN;

let underscoreNum: number = 1_000_000;

string

string

  • 다른 언어에서와 마찬가지로이 텍스트 형식을 참조하기 위해 `string` 형식을 사용합니다.

  • JavaScript 와 마찬가지로, TypeScript는
    문자열 데이터를 둘러싸기 위해 큰 따옴표 ( " ) 나, 작은 따옴표 ( ' ) 를 사용합니다.

let name: string = "mark";

name = 'anna';

Template String

  • 행에 걸쳐 있거나, 표현식을 넣을 수 있는 문자열

  • 이 문자열은 backtick (= backquote) 기호에 둘러쌓여 있습니다.

  • 포함된 표현식은 `${ expr }` 와 같은 형태로 사용합니다.

let fullName: string = `Bob Bobbington`;
let age: number = 38;

let sentence: string = `Hello, my name is ${ fullName }.

I'll be ${ age + 1 } years old next month.`;

// template string 을 사용하지 않을 경우
let sentence: string = "Hello, my name is " + fullName + ".\n\n" +
    "I'll be " + (age + 1) + " years old next month.";

symbol

Symbol

  • ECMAScript 2015 의 Symbol 입니다.

  • new Symbol 로 사용할 수 없습니다.

  • Symbol 을 함수로 사용해서 symbol 타입을 만들어낼 수 있습니다.

console.log(Symbol('foo') === Symbol('foo'));

Symbol

  • 프리미티브 타입의 값을 담아서 사용합니다.

  • 고유하고 수정불가능한 값으로 만들어줍니다.

  • 그래서 주로 접근을 제어하는데 쓰는 경우가 많았습니다.

let sym = Symbol();

let obj = {
    [sym]: "value"
};

console.log(obj[sym]); // "value"

null & undefined

Undefined & Null

  • In TypeScript, both undefined and null actually have their types named undefined and null respectively.
    TypeScript 에서, undefined 와 null 은 실제로 각각 undefined 및 null 이라는 타입을 가집니다.

  • Much like void, they’re not extremely useful on their own:
    void 와 마찬가지로, 그 자체로는 그다지 유용하지 않습니다.

  • 둘다 소문자만 존재합니다.

// 이 변수들에 할당할 수 있는 것들은 거의 없다.

let u: undefined = undefined;
let n: null = null;

undefined & null are subtypes
of all other types.

  • 설정을 하지 않으면 그렇습니다.

  • number 에 null 또는 undefined 를 할당할 수 있다는 의미입니다.

  • 하지만, 컴파일 옵션에서 `--strictNullChecks`사용하면, null 과 undefined 는 void 나 자기 자신들에게만 할당할 수 있습니다.

    • 이 경우, null 과 undefined 를 할당할 수 있게 하려면, union type 을 이용해야 합니다.

let name: string = null;
let age: number = undefined;

// strictNullChecks => true
// Type 'null' is not assignable to type 'string'.
let name: string = null; (X)

// null => null || void, undefined => undefined || void
// Type 'null' is not assignable to type 'undefined'.
let u: undefined = null; // (X)

let v: void = undefined; // (O)

let union: string | null | undefined = 'str';

null in JavaScript 

  • null 이라는 값으로 할당된 것을 null 이라고 합니다.

  • 무언가가 있는데, 사용할 준비가 덜 된 상태.

  • null 이라는 타입은 null 이라는 값만 가질 수 있습니다.

  • 런타임에서 typeof 연산자를 이용해서 알아내면, object 입니다.

let n: null = null;

console.log(n); // null
console.log(typeof n); // object

undefined in JavaScript 

  • 값을 할당하지 않은 변수는 undefined 라는 값을 가집니다.

  • 무언가가 아예 준비가 안된 상태

  • object 의 property 가 없을 때도 undefined 입니다.

  • 런타임에서 typeof 연산자를 이용해서 알아내면, undefined 입니다.

let u: undefined = undefined;

console.log(u); // undefined
console.log(typeof u); // undefined

object

// create by object literal
const person1 = {name: 'Mark', age: 39};

// person1 is not "object" type.
// person1 is "{name: string, age: number}" type.


// create by Object.create
const person2 = Object.create({name: 'Mark', age: 39});

object

  • a type that represents the non-primitive type

  • "primitive type 이 아닌 것" 을 나타내고 싶을 때 사용하는 타입

 

non-primitive type

  • not number, string, boolean, bigint, symbol, null, or undefined.

let obj: object = {};

obj = {name: 'Mark'};

obj = [{name: 'Mark'}];

obj = 39; // Error

obj = 'Mark'; // Error

obj = true; // Error

obj = 100n; // Error

obj = Symbol(); // Error

obj = null; // Error

obj = undefined; // Error
declare function create(o: object | null): void;

create({ prop: 0 });

create(null);

create(42); // Error

create("string"); // Error

create(false); // Error

create(undefined); // Error


// Object.create
Object.create(0); // Error

Array

Array

  • 원래 자바스크립트에서 array 는 객체입니다.

  • 사용방법

    • Array<타입>

    • 타입[]

let list: number[] = [1, 2, 3];

let list: Array<number> = [1, 2, 3];

Tuple

Tuple

  • 배열인데 타입이 한가지가 아닌 경우

  • 마찬가지로 객체입니다.

  • 꺼내 사용할때 주의가 필요합니다.

    • 배열을 Destructuting 하면 타입이 제대로 얻어집니다.

let x: [string, number]; // Declare a tuple type
x = ["hello", 10]; // OK
x = [10, "hello"]; // Error

x[3] = "world"; // Type '"world"' is not assignable to type 'undefined'.

const person: [string, number] = ["mark", 35];

const [first, second, third] = person;

any

any

  • 어떤 타입이어도 상관없는 타입입니다.

  • 이걸 최대한 쓰지 않는게 핵심입니다.

  • 왜냐면 컴파일 타임에 타입 체크가 정상적으로 이뤄지지 않기 때문입니다.

  • 그래서 컴파일 옵션 중에는 any 를 써야하는데 쓰지 않으면 오류를 뱉도록 하는 옵션도 있습니다.

    • noImplicitAny

function returnAny(message): any {
    console.log(message);
}

returnVoid('리턴은 아무거나');

any

  • The any will continue to propagate through your objects:
    any 는 계속해서 개체를 통해 전파됩니다.

  • After all, remember that all the convenience of any comes at the cost of losing type safety.
    결국, 모든 편의는 타입 안전성을 잃는 대가로 온다는 것을 기억하십시오.
  • Type safety is one of the main motivations for using TypeScript and you should try to avoid using any when not necessary.
    타입 안전성은 TypeScript 를 사용하는 주요 동기 중 하나이며 필요하지 않은 경우에는 any 를 사용하지 않도록 해야합니다.
let looselyTyped: any = {};

let d = looselyTyped.a.b.c.d;
//  ^ = let d: any

Avoid leaking any

  • any 는 존재할 수 밖에 없다.
  • any 로 지정된 값을 이용해서 새로운 값으로 만들어 사용하는 지점에서
    누수를 막아주도록 노력이 필요하다.
function leakingAny(obj: any) {
  const a = obj.num; // const a: number = obj.num;
  const b = a + 1;
  return b;
}

const c = leakingAny({num: 0});
const d: string = c.indexOf('0');

unknown

  • We may need to describe the type of variables that we do not know when we are writing an application.
    응용 프로그램을 작성할 때 모르는 변수의 타입을 묘사해야 할 수도 있습니다.

 

  • These values may come from dynamic content – e.g. from the user – or we may want to intentionally accept all values in our API.
    이러한 값은 동적 콘텐츠 (예 : 사용자로부터, 또는 우리 API 의 모든 값을 의도적으로 수락하기를 원할 수 있습니다.

 

  • In these cases, we want to provide a type that tells the compiler and future readers that this variable could be anything, so we give it the unknown type.
    이 경우, 컴파일러와 미래의 코드를 읽는 사람에게 이 변수가 무엇이든 될 수 있음을 알려주는 타입을 제공하기를 원하므로 unknown 타입을 제공합니다.
declare const maybe: unknown;
// 'maybe' could be a string, object, boolean, undefined, or other types
const aNumber: number = maybe; // Type 'unknown' is not assignable to type 'number'.

if (maybe === true) {
  // TypeScript knows that maybe is a boolean now
  const aBoolean: boolean = maybe;
  // So, it cannot be a string
  const aString: string = maybe; // Type 'boolean' is not assignable to type 'string'.
}

if (typeof maybe === "string") {
  // TypeScript knows that maybe is a string
  const aString: string = maybe;
  // So, it cannot be a boolean
  const aBoolean: boolean = maybe; // Type 'string' is not assignable to type 'boolean'.
}

unknown

  • typeof 검사, 비교 검사 또는 고급 타입 가드를 수행하여 보다 구체적인 변수로 좁힐 수 있습니다.

unknown

  • Typescript 3.0 버전부터 지원

  • any와 짝으로 any 보다 Type-safe한 타입

    • any와 같이 아무거나 할당할 수 있다.

    • 컴파일러가 타입을 추론할 수 있게끔 타입의 유형을 좁히거나

    • 타입을 확정해주지 않으면 다른 곳에 할당 할 수 없고, 사용할 수 없다.

  • unknown 타입을 사용하면 runtime error를 줄일 수 있을 것 같다.

    • 사용 전에 데이터의 일부 유형의 검사를 수행해야 함을 알리는 API에 사용할 수 있을 것 같다.

never

never

  • 리턴에 사용됩니다.

  • 리턴에 사용되는 경우, 아래 3가지 정도의 경우가 대부분입니다.

// Function returning never must have unreachable end point
function error(message: string): never {
    throw new Error(message);
}

// Inferred return type is never
function fail() {
    return error("Something failed");
}

// Function returning never must have unreachable end point
function infiniteLoop(): never {
    while (true) {
    }
}

never

  • never 타입은 모든 타입의 subtype 이며, 모든 타입에 할당 할 수 있습니다.

  • 하지만, never 에는 그 어떤 것도 할당할 수 없습니다.

  • any 조차도 never 에게 할당 할 수 없습니다.

  • 잘못된 타입을 넣는 실수를 막고자 할 때 사용하기도 합니다.

let a: string = 'hello';

if (typeof a !== 'string') {
    let b: never = a;
}

type Indexable<T> = T extends string ? T & { [index: string]: any } : never;

void

void

  • 어떤 타입도 가지지 않는 빈 상태를 의미합니다.

  • 값은 없고 타입만 있습니다.

  • 소문자입니다.

  • 일반적으로 값을 반환하지 않는 함수의 리턴 타입으로 사용합니다.
    그 외에는 사용할 일이 거의 없습니다.

  • 할당이 가능한 값은 undefined 입니다.

function returnVoid(message): void {
    console.log(message);
}

returnVoid('리턴이 없다');

let unusable: void = undefined;

3. Type System

3-1) 작성자와 사용자의 관점으로 코드 바라보기

3-2) Structural Type System vs Nominal Type System

3-3) 타입 호환성 (Type Compatibility)

3-4) 타입 별칭 (Type Alias)

any

// 입력은 마음대로,
// 함수 구현이 자유롭게 => 자유가 항상 좋은건 아니다.
function fany(a: any): number | string | void {
  a.toString();

  if (typeof a === 'number') {
    return a * 38;
  } else if (typeof a === 'string') {
    return `Hello ${a}`;
  }
}

console.log(fany(10)); // 380
console.log(fany('Mark')); // Hello Mark
console.log(fany(true)); // undefined

any 대신 unknown

// 입력은 마음대로,
// 함수 구현은 문제 없도록
function funknown(a: unknown): number | string | void {
  a.toString(); // error! Object is of type 'unknown'.

  if (typeof a === 'number') {
    return a * 38;
  } else if (typeof a === 'string') {
    return `Hello ${a}`;
  }
}

console.log(funknown(10)); // 380
console.log(funknown('Mark')); // Hello Mark
console.log(funknown(true)); // undefined

작성자와 사용자의 관점으로

코드 바라보기

타입 시스템

 

  • 컴파일러에게 사용하는 타입을 명시적으로 지정하는 시스템

  • 컴파일러가 자동으로 타입을 추론하는 시스템

타입스크립트의 타입 시스템

 

  • 타입을 명시적으로 지정할 수 있다.

  • 타입을 명시적으로 지정하지 않으면, 타입스크립트 컴파일러가 자동으로 타입을 추론

형태를 정해둔 함수

자신의 코드에서 해당 함수를 사용하는 사용자

해당 함수를 구현하는 구현자

타입이란 해당 변수가 할 수 있는 일을 결정합니다.

// JavaScript

// f1 이라는 함수의 body 에서는 a 를 사용할 것 입니다.
// a 가 할 수 있는 일은 a 의 타입이 결정합니다.

function f1(a) {
  return a;
}

함수 사용법에 대한 오해를 야기하는 자바스크립트

// JavaScript

// (f2 실행의 결과가 NaN 을 의도한 것이 아니라면)
// 이 함수의 작성자는 매개변수 a 가 number 타입이라는 가정으로 함수를 작성했습니다.

function f2(a) {
  return a * 38;
}

// 사용자는 사용법을 숙지하지 않은 채, 문자열을 사용하여 함수를 실행했습니다.

console.log(f2(10)); // 380
console.log(f2('Mark')); // NaN

타입스크립트의 추론에 의지하는 경우

// 타입스크립트 코드지만,
// a 의 타입을 명시적으로 지정하지 않은 경우이가 때문에 a 는 any 로 추론됩니다.
// 함수의 리턴 타입은 number 로 추론됩니다. (NaN 도 number 의 하나입니다.)

function f3(a) {
  return a * 38;
}

// 사용자는 a 가 any 이기 때문에, 사용법에 맞게 문자열을 사용하여 함수를 실행했습니다.

console.log(f3(10)); // 380
console.log(f3('Mark') + 5); // NaN

noImplicitAny 옵션을 켜면


타입을 명시적으로 지정하지 않은 경우,

타입스크립트가 추론 중 `any` 라고 판단하게 되면,

컴파일 에러를 발생시켜

명시적으로 지정하도록 유도한다.

noImplicitAny 에 의한 방어

// error TS7006: Parameter 'a' implicitly has an 'any' type.

function f3(a) {
  return a * 38;
}

// 사용자의 코드를 실행할 수 없습니다. 컴파일이 정상적으로 마무리 될 수 있도록 수정해야 합니다.

console.log(f3(10));
console.log(f3('Mark') + 5);

number 타입으로 추론된 리턴 타입

// 매개변수의 타입은 명시적으로 지정했습니다.
// 명시적으로 지정하지 않은 함수의 리턴 타입은 number 로 추론됩니다.

function f4(a: number) {
  if (a > 0) {
    return a * 38;
  }
}

// 사용자는 사용법에 맞게 숫자형을 사용하여 함수를 실행했습니다.
// 해당 함수의 리턴 타입은 number 이기 때문에, 타입에 따르면 이어진 연산을 바로 할 수 있습니다.
// 하지만 실제 undefined + 5 가 실행되어 NaN 이 출력됩니다.

console.log(f4(5)); // 190
console.log(f4(-5) + 5); // NaN

strictNullChecks 옵션을 켜면


모든 타입에 자동으로 포함되어 있는

`null` 과 `undefined` 를

제거해줍니다.

number | undefined 타입으로 추론된 리턴 타입

// 매개변수의 타입은 명시적으로 지정했습니다.
// 명시적으로 지정하지 않은 함수의 리턴 타입은 number | undefined 로 추론됩니다.

function f4(a: number) {
  if (a > 0) {
    return a * 38;
  }
}

// 사용자는 사용법에 맞게 숫자형을 사용하여 함수를 실행했습니다.
// 해당 함수의 리턴 타입은 number | undefined 이기 때문에,
// 타입에 따르면 이어진 연산을 바로 할 수 없습니다.
// 컴파일 에러를 고쳐야하기 하기 때문에 사용자와 작성자가 의논을 해야합니다.

console.log(f4(5));
console.log(f4(-5) + 5); // error TS2532: Object is possibly 'undefined'.

명시적으로 리턴 타입을 지정해야할까?

// 매개변수의 타입과 함수의 리턴 타입을 명시적으로 지정했습니다.
// 실제 함수 구현부의 리턴 타입과 명시적으로 지정한 타입이 일치하지 않아 컴파일 에러가 발생합니다.

// error TS2366: Function lacks ending return statement and return type does not include 'undefined'.
function f5(a: number): number {
  if (a > 0) {
    return a * 38;
  }
}

noImplicitReturns 옵션을 켜면


함수 내에서 모든 코드가 값을 리턴하지 않으면,

컴파일 에러를 발생시킨다.

모든 코드에서 리턴을 직접해야한다.

// if 가 아닌 경우 return 을 직접 하지 않고 코드가 종료된다.

// error TS7030: Not all code paths return a value.
function f5(a: number) {
  if (a > 0) {
    return a * 38;
  }
}

매개변수에 object 가 들어오는 경우

// JavaScript

function f6(a) {
  return `이름은 ${a.name} 이고, 연령대는 ${
    Math.floor(a.age / 10) * 10
  }대 입니다.`;
}

console.log(f6({ name: 'Mark', age: 38 })); // 이름은 Mark 이고, 연령대는 30대 입니다.
console.log(f6('Mark')); // 이름은 undefined 이고, 연령대는 NaN대 입니다.

object literal type

function f7(a: { name: string; age: number }): string {
  return `이름은 ${a.name} 이고, 연령대는 ${
    Math.floor(a.age / 10) * 10
  }대 입니다.`;
}

console.log(f7({ name: 'Mark', age: 38 })); // 이름은 Mark 이고, 연령대는 30대 입니다.
console.log(f7('Mark')); // error TS2345: Argument of type 'string' is not assignable to parameter of type '{ name: string; age: number; }'.

나만의 타입을 만드는 방법

interface PersonInterface {
  name: string;
  age: number;
}

type PersonTypeAlias = {
  name: string;
  age: number;
};

function f8(a: PersonInterface): string {
  return `이름은 ${a.name} 이고, 연령대는 ${
    Math.floor(a.age / 10) * 10
  }대 입니다.`;
}

console.log(f8({ name: 'Mark', age: 38 })); // 이름은 Mark 이고, 연령대는 30대 입니다.
console.log(f8('Mark')); // error TS2345: Argument of type 'string' is not assignable to parameter of type 'PersonInterface'.

Structural Type System

vs

Nominal Type System

구조적 타입 시스템 Structural Type System

  • 타입의 호환성과 서브타입을 결정할 때 해당 타입의 구조(형태)나 멤버에 주로 의존합니다.

  • 예를 들어, 두 object 가 같은 필드와 메서드를 갖는다면, 타입 시스템적으로 호환이 됩니다.

  • 일부 정적 타입 언어 (타입스크립트) 에서 사용됩니다.

명목적 타입 시스템 Nominal Type System

  • 타입의 호환성은 타입의 이름 또는 선언에 기반합니다.

  • 실제 구조나 내용물에 관계없이 이름이 동일하면 두 타입이 동일하다고 간주됩니다.

  • 대부분의 전통적인 정적 타입 언어 (Java, C#) 에서 사용됩니다.

구조적 타입 시스템 Structural Type System

interface Duck {
  quack(): void;
  walk(): void;
}

function makeItQuack(duck: Duck) {
  duck.quack();
}

const someObject = {
  quack: () => console.log("Quack!"),
  walk: () => console.log("Walking..."),
  run: () => console.log("Running..."),
};

// someObject는 Duck 인터페이스를 명시적으로 구현하지 않았지만 구조적으로 호환되므로 이 함수 호출은 유효합니다.
makeItQuack(someObject);

명목적 타입 시스템 Nominal Type System

class Tiger {
    public void roar() {
        System.out.println("Roar!");
    }
}

class Lion {
    public void roar() {
        System.out.println("Roar!");
    }
}

public class Zoo {
    public static void main(String[] args) {
        Tiger tiger = new Tiger();
        Lion lion = new Lion();

        // 다음 코드는 컴파일 오류를 발생시킵니다.
        // tiger = lion; // Type mismatch: cannot convert from Lion to Tiger
    }
}

structural type system - 구조가 같으면, 같은 타입이다.

interface IPerson {
  name: string;
  age: number;
  speak(): string;
}

type PersonType = {
  name: string;
  age: number;
  speak(): string;
};

let personInterface: IPerson = {} as any;
let personType: PersonType = {} as any;

personInterface = personType;
personType = personInterface;

nominal type system - 구조가 같아도 이름이 다르면, 다른 타입이다.

type PersonID = string & { readonly brand: unique symbol };

function PersonID(id: string): PersonID {
  return id as PersonID;
}

function getPersonById(id: PersonID) {}

getPersonById(PersonID('id-aaaaaa'));
getPersonById('id-aaaaaa'); // error TS2345: Argument of type 'string' is not assignable to parameter of type 'PersonID'. Type 'string' is not assignable to type '{ readonly brand: unique symbol; }'.

덕 타이핑 Duck Typing 과의 차이점

구조적 타입 시스템의 개념은 주로 정적 타입 언어의 컨텍스트에서 언급됩니다.

이는 정적 타입 언어에서 타입 호환성을 결정하는 방식으로 사용되기 때문입니다.

동적 타입 언어는 실행 시점에 타입을 결정하므로 구조적 또는 명목적 타입 시스템의 구분이 크게 적용되지 않습니다.

그럼에도 불구하고, 동적 타입 언어의 일부 기능이나 패턴은 구조적 타입의 특성을 반영할 수 있습니다.

예를 들어, 파이썬의 "duck typing" 은 구조적 타입의 개념과 유사한 면이 있습니다.

"duck typing" 은 객체의 실제 타입 대신 객체가 어떤 메서드나 속성을 가지고 있는지에 따라 처리하는 방식을 말합니다.

https://ko.wikipedia.org/wiki/%EB%8D%95_%ED%83%80%EC%9D%B4%ED%95%91

duck typing

class Duck:
   def sound(self):
      print u"꽥꽥"

class Dog:
   def sound(self):
      print u"멍멍"

def get_sound(animal):
   animal.sound()

def main():
   bird = Duck()
   dog = Dog()
   get_sound(bird)
   get_sound(dog)

만약 어떤 새가 오리처럼 걷고, 헤엄치고, 꽥꽥거리는 소리를 낸다면

나는 그 새를 오리라고 부를 것이다.

타입스크립트는 구조적 타입 시스템을 사용

구조적 타입 시스템의 장점은 타입의 실제 구조에 중점을 둠으로써 더 유연한 프로그래밍 패턴을 허용한다는 것입니다. 그렇기 때문에 기능적으로 유사한 객체나 데이터를 여러 위치에서 쉽게 사용할 수 있습니다.

타입 호환성

(Type Compatibility)

서브 타입 (1)

// sub1 타입은 sup1 타입의 서브 타입이다.
let sub1: 1 = 1;
let sup1: number = sub1;
sub1 = sup1; // error! Type 'number' is not assignable to type '1'.

// sub2 타입은 sup2 타입의 서브 타입이다.
let sub2: number[] = [1];
let sup2: object = sub2;
sub2 = sup2; // error! Type '{}' is missing the following properties from type 'number[]': length, pop, push, concat, and 16 more.

// sub3 타입은 sup3 타입의 서브 타입이다.
let sub3: [number, number] = [1, 2];
let sup3: number[] = sub3;
sub3 = sup3; // error! Type 'number[]' is not assignable to type '[number, number]'. Target requires 2 element(s) but source may have fewer.

서브 타입 (2)

// sub4 타입은 sup4 타입의 서브 타입이다.
let sub4: number = 1;
let sup4: any = sub4;
sub4 = sup4;

// sub5 타입은 sup5 타입의 서브 타입이다.
let sub5: never = 0 as never;
let sup5: number = sub5;
sub5 = sup5; // error! Type 'number' is not assignable to type 'never'.

class Animal {}
class Dog extends Animal {
  eat() {}
}

// sub6 타입은 sup6 타입의 서브 타입이다.
let sub6: Dog = new Dog();
let sup6: Animal = sub6;
sub6 = sup6; // error! Property 'eat' is missing in type 'SubAnimal' but required in type 'SubDog'.

1. 같거나 서브 타입인 경우, 할당이 가능하다. => 공변

// primitive type
let sub7: string = '';
let sup7: string | number = sub7;

// object - 각각의 프로퍼티가 대응하는 프로퍼티와 같거나 서브타입이어야 한다.
let sub8: { a: string; b: number } = { a: '', b: 1 };
let sup8: { a: string | number; b: number } = sub8;

// array - object 와 마찬가지
let sub9: Array<{ a: string; b: number }> = [{ a: '', b: 1 }];
let sup9: Array<{ a: string | number; b: number }> = sub8;

2. 함수의 매개변수 타입만 같거나 슈퍼타입인 경우, 할당이 가능하다. => 반병

class Person {}
class Developer extends Person {
  coding() {}
}
class StartupDeveloper extends Developer {
  burning() {}
}

function tellme(f: (d: Developer) => Developer) {}

// Developer => Developer 에다가 Developer => Developer 를 할당하는 경우
tellme(function dToD(d: Developer): Developer {
  return new Developer();
});

// Developer => Developer 에다가 Person => Developer 를 할당하는 경우
tellme(function pToD(d: Person): Developer {
  return new Developer();
});

// Developer => Developer 에다가 StartipDeveloper => Developer 를 할당하는 경우
tellme(function sToD(d: StartupDeveloper): Developer {
  return new Developer();
});

strictFunctionTypes 옵션을 켜면

 

함수를 할당할 시에 함수의 매개변수 타입이 같거나 슈퍼타입인 경우가 아닌 경우,

에러를 통해 경고한다.

타입 별칭

(Type Alias)

타입 별칭 (별명)

  • Interface 랑 비슷해 보입니다.

  • Primitive, Union Type, Tuple, Function

  • 기타 직접 작성해야하는 타입을 다른 이름을 지정할 수 있습니다.

  • 만들어진 타입의 refer 로 사용하는 것이지 타입을 만드는것은 아닙니다.

Aliasing Primitive

type MyStringType = string;

const str = 'world';

let myStr: MyStringType = 'hello';
myStr = str;

/*

별 의미가 없다..

*/

Aliasing Union Type

let person: string | number = 0;
person = 'Mark';

type StringOrNumber = string | number;

let another: StringOrNumber = 0;
another = 'Anna';

/*

1. 유니온 타입은 A 도 가능하고 B 도 가능한 타입
2. 길게 쓰는걸 짧게

*/

Aliasing Tuple

let person: [string, number] = ['Mark', 35];

type PersonTuple = [string, number];

let another: PersonTuple = ['Anna', 24];

/*

1. 튜플 타입에 별칭을 줘서 여러군데서 사용할 수 있게 한다.

*/

Aliasing Function

type EatType = (food: string) => void;

4. TypeScript Compiler

4-1) Compilation Context    4-2) tsconfig schema

4-3) compileOnSave    4-4) extends

4-5) files, include, exclude    4-6) compileOptions - typeRoots, types

4-7) compileOptions - target 과 lib    4-8) compileOptions - outDir, outFile

4-9) compileOptions - strict

Compilation Context

The compilation context is basically just a fancy term for grouping of the files that TypeScript will parse and analyze to determine what is valid and what isn't.

 

Along with the information about which files, the compilation context contains information about which compiler options are in use.

 

A great way to define this logical grouping
(we also like to use the term project) is using a tsconfig.json file.

TypeScript
Compiler

Compilation

Context

tsconfig schema

{
  "title": "JSON schema for the TypeScript compiler's configuration file",
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "https://json.schemastore.org/tsconfig",
  "definitions": {
    "//": {
      "explainer": "https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#overview",
      "reference": "https://www.typescriptlang.org/tsconfig",
      "reference metadata": "https://github.com/microsoft/TypeScript-Website/blob/v2/packages/tsconfig-reference/scripts/tsconfigRules.ts"
    },
    "filesDefinition": {
      "properties": {
        "files": {
          "description": "If no 'files' or 'include' property is present in a tsconfig.json, the compiler defaults to including all files in the containing directory and subdirectories except those specified by 'exclude'. When a 'files' property is specified, only those files and those specified by 'include' are included.",
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "string"
          }
        }
      }
    },
    "excludeDefinition": {
      "properties": {
        "exclude": {
          "description": "Specifies a list of files to be excluded from compilation. The 'exclude' property only affects the files included via the 'include' property and not the 'files' property. Glob patterns require TypeScript version 2.0 or later.",
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "string"
          }
        }
      }
    },
    "includeDefinition": {
      "properties": {
        "include": {
          "description": "Specifies a list of glob patterns that match files to be included in compilation. If no 'files' or 'include' property is present in a tsconfig.json, the compiler defaults to including all files in the containing directory and subdirectories except those specified by 'exclude'. Requires TypeScript version 2.0 or later.",
          "type": "array",
          "uniqueItems": true,
          "items": {
            "type": "string"
          }
        }
      }
    },
    "compileOnSaveDefinition": {
      "properties": {
        "compileOnSave": {
          "description": "Enable Compile-on-Save for this project.",
          "type": "boolean"
        }
      }
    },
    "extendsDefinition": {
      "properties": {
        "extends": {
          "description": "Path to base configuration file to inherit from. Requires TypeScript version 2.1 or later.",
          "type": "string"
        }
      }
    },
    "compilerOptionsDefinition": {
      "properties": {
        "compilerOptions": {
          "type": "object",
          "description": "Instructs the TypeScript compiler how to compile .ts files.",
          "properties": {
            "charset": {
              "description": "No longer supported. In early versions, manually set the text encoding for reading files.",
              "type": "string",
              "markdownDescription": "No longer supported. In early versions, manually set the text encoding for reading files.\n\nSee more: https://www.typescriptlang.org/tsconfig#charset"
            },
            "composite": {
              "description": "Enable constraints that allow a TypeScript project to be used with project references.",
              "type": "boolean",
              "default": true,
              "markdownDescription": "Enable constraints that allow a TypeScript project to be used with project references.\n\nSee more: https://www.typescriptlang.org/tsconfig#composite"
            },
            "declaration": {
              "description": "Generate .d.ts files from TypeScript and JavaScript files in your project.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Generate .d.ts files from TypeScript and JavaScript files in your project.\n\nSee more: https://www.typescriptlang.org/tsconfig#declaration"
            },
            "declarationDir": {
              "description": "Specify the output directory for generated declaration files.",
              "type": ["string", "null"],
              "markdownDescription": "Specify the output directory for generated declaration files.\n\nSee more: https://www.typescriptlang.org/tsconfig#declarationDir"
            },
            "diagnostics": {
              "description": "Output compiler performance information after building.",
              "type": "boolean",
              "markdownDescription": "Output compiler performance information after building.\n\nSee more: https://www.typescriptlang.org/tsconfig#diagnostics"
            },
            "disableReferencedProjectLoad": {
              "description": "Reduce the number of projects loaded automatically by TypeScript.",
              "type": "boolean",
              "markdownDescription": "Reduce the number of projects loaded automatically by TypeScript.\n\nSee more: https://www.typescriptlang.org/tsconfig#disableReferencedProjectLoad"
            },
            "noPropertyAccessFromIndexSignature": {
              "description": "Enforces using indexed accessors for keys declared using an indexed type",
              "type": "boolean",
              "markdownDescription": "Enforces using indexed accessors for keys declared using an indexed type\n\nSee more: https://www.typescriptlang.org/tsconfig#noPropertyAccessFromIndexSignature"
            },
            "emitBOM": {
              "description": "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.\n\nSee more: https://www.typescriptlang.org/tsconfig#emitBOM"
            },
            "emitDeclarationOnly": {
              "description": "Only output d.ts files and not JavaScript files.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Only output d.ts files and not JavaScript files.\n\nSee more: https://www.typescriptlang.org/tsconfig#emitDeclarationOnly"
            },
            "incremental": {
              "description": "Save .tsbuildinfo files to allow for incremental compilation of projects.",
              "type": "boolean",
              "markdownDescription": "Save .tsbuildinfo files to allow for incremental compilation of projects.\n\nSee more: https://www.typescriptlang.org/tsconfig#incremental"
            },
            "tsBuildInfoFile": {
              "description": "Specify the folder for .tsbuildinfo incremental compilation files.",
              "default": ".tsbuildinfo",
              "type": "string",
              "markdownDescription": "Specify the folder for .tsbuildinfo incremental compilation files.\n\nSee more: https://www.typescriptlang.org/tsconfig#tsBuildInfoFile"
            },
            "inlineSourceMap": {
              "description": "Include sourcemap files inside the emitted JavaScript.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Include sourcemap files inside the emitted JavaScript.\n\nSee more: https://www.typescriptlang.org/tsconfig#inlineSourceMap"
            },
            "inlineSources": {
              "description": "Include source code in the sourcemaps inside the emitted JavaScript.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Include source code in the sourcemaps inside the emitted JavaScript.\n\nSee more: https://www.typescriptlang.org/tsconfig#inlineSources"
            },
            "jsx": {
              "description": "Specify what JSX code is generated.",
              "enum": [
                "preserve",
                "react",
                "react-jsx",
                "react-jsxdev",
                "react-native"
              ]
            },
            "reactNamespace": {
              "description": "Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit.",
              "type": "string",
              "default": "React",
              "markdownDescription": "Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit.\n\nSee more: https://www.typescriptlang.org/tsconfig#reactNamespace"
            },
            "jsxFactory": {
              "description": "Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'",
              "type": "string",
              "default": "React.createElement",
              "markdownDescription": "Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'\n\nSee more: https://www.typescriptlang.org/tsconfig#jsxFactory"
            },
            "jsxFragmentFactory": {
              "description": "Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'.",
              "type": "string",
              "default": "React.Fragment",
              "markdownDescription": "Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'.\n\nSee more: https://www.typescriptlang.org/tsconfig#jsxFragmentFactory"
            },
            "jsxImportSource": {
              "description": "Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.`",
              "type": "string",
              "default": "react",
              "markdownDescription": "Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.`\n\nSee more: https://www.typescriptlang.org/tsconfig#jsxImportSource"
            },
            "listFiles": {
              "description": "Print all of the files read during the compilation.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Print all of the files read during the compilation.\n\nSee more: https://www.typescriptlang.org/tsconfig#listFiles"
            },
            "mapRoot": {
              "description": "Specify the location where debugger should locate map files instead of generated locations.",
              "type": "string",
              "markdownDescription": "Specify the location where debugger should locate map files instead of generated locations.\n\nSee more: https://www.typescriptlang.org/tsconfig#mapRoot"
            },
            "module": {
              "description": "Specify what module code is generated.",
              "type": "string",
              "anyOf": [
                {
                  "enum": [
                    "CommonJS",
                    "AMD",
                    "System",
                    "UMD",
                    "ES6",
                    "ES2015",
                    "ES2020",
                    "ESNext",
                    "None"
                  ]
                },
                {
                  "pattern": "^([Cc][Oo][Mm][Mm][Oo][Nn][Jj][Ss]|[AaUu][Mm][Dd]|[Ss][Yy][Ss][Tt][Ee][Mm]|[Ee][Ss]([356]|201[567]|2020|[Nn][Ee][Xx][Tt])|[Nn][Oo][Nn][Ee])$"
                }
              ],
              "markdownDescription": "Specify what module code is generated.\n\nSee more: https://www.typescriptlang.org/tsconfig#module"
            },
            "moduleResolution": {
              "description": "Specify how TypeScript looks up a file from a given module specifier.",
              "type": "string",
              "anyOf": [
                {
                  "enum": ["Classic", "Node"]
                },
                {
                  "pattern": "^(([Nn]ode)|([Cc]lassic))$"
                }
              ],
              "default": "classic",
              "markdownDescription": "Specify how TypeScript looks up a file from a given module specifier.\n\nSee more: https://www.typescriptlang.org/tsconfig#moduleResolution"
            },
            "newLine": {
              "description": "Set the newline character for emitting files.",
              "type": "string",
              "anyOf": [
                {
                  "enum": ["crlf", "lf"]
                },
                {
                  "pattern": "^(CRLF|LF|crlf|lf)$"
                }
              ],
              "markdownDescription": "Set the newline character for emitting files.\n\nSee more: https://www.typescriptlang.org/tsconfig#newLine"
            },
            "noEmit": {
              "description": "Disable emitting file from a compilation.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disable emitting file from a compilation.\n\nSee more: https://www.typescriptlang.org/tsconfig#noEmit"
            },
            "noEmitHelpers": {
              "description": "Disable generating custom helper functions like `__extends` in compiled output.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disable generating custom helper functions like `__extends` in compiled output.\n\nSee more: https://www.typescriptlang.org/tsconfig#noEmitHelpers"
            },
            "noEmitOnError": {
              "description": "Disable emitting files if any type checking errors are reported.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disable emitting files if any type checking errors are reported.\n\nSee more: https://www.typescriptlang.org/tsconfig#noEmitOnError"
            },
            "noImplicitAny": {
              "description": "Enable error reporting for expressions and declarations with an implied `any` type..",
              "type": "boolean",
              "markdownDescription": "Enable error reporting for expressions and declarations with an implied `any` type..\n\nSee more: https://www.typescriptlang.org/tsconfig#noImplicitAny"
            },
            "noImplicitThis": {
              "description": "Enable error reporting when `this` is given the type `any`.",
              "type": "boolean",
              "markdownDescription": "Enable error reporting when `this` is given the type `any`.\n\nSee more: https://www.typescriptlang.org/tsconfig#noImplicitThis"
            },
            "noUnusedLocals": {
              "description": "Enable error reporting when a local variables aren't read.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Enable error reporting when a local variables aren't read.\n\nSee more: https://www.typescriptlang.org/tsconfig#noUnusedLocals"
            },
            "noUnusedParameters": {
              "description": "Raise an error when a function parameter isn't read",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Raise an error when a function parameter isn't read\n\nSee more: https://www.typescriptlang.org/tsconfig#noUnusedParameters"
            },
            "noLib": {
              "description": "Disable including any library files, including the default lib.d.ts.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disable including any library files, including the default lib.d.ts.\n\nSee more: https://www.typescriptlang.org/tsconfig#noLib"
            },
            "noResolve": {
              "description": "Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project.\n\nSee more: https://www.typescriptlang.org/tsconfig#noResolve"
            },
            "noStrictGenericChecks": {
              "description": "Disable strict checking of generic signatures in function types.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disable strict checking of generic signatures in function types.\n\nSee more: https://www.typescriptlang.org/tsconfig#noStrictGenericChecks"
            },
            "skipDefaultLibCheck": {
              "description": "Skip type checking .d.ts files that are included with TypeScript.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Skip type checking .d.ts files that are included with TypeScript.\n\nSee more: https://www.typescriptlang.org/tsconfig#skipDefaultLibCheck"
            },
            "skipLibCheck": {
              "description": "Skip type checking all .d.ts files.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Skip type checking all .d.ts files.\n\nSee more: https://www.typescriptlang.org/tsconfig#skipLibCheck"
            },
            "outFile": {
              "description": "Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output.",
              "type": "string",
              "markdownDescription": "Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output.\n\nSee more: https://www.typescriptlang.org/tsconfig#outFile"
            },
            "outDir": {
              "description": "Specify an output folder for all emitted files.",
              "type": "string",
              "markdownDescription": "Specify an output folder for all emitted files.\n\nSee more: https://www.typescriptlang.org/tsconfig#outDir"
            },
            "preserveConstEnums": {
              "description": "Disable erasing `const enum` declarations in generated code.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disable erasing `const enum` declarations in generated code.\n\nSee more: https://www.typescriptlang.org/tsconfig#preserveConstEnums"
            },
            "preserveSymlinks": {
              "description": "Disable resolving symlinks to their realpath. This correlates to the same flag in node.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disable resolving symlinks to their realpath. This correlates to the same flag in node.\n\nSee more: https://www.typescriptlang.org/tsconfig#preserveSymlinks"
            },
            "preserveWatchOutput": {
              "description": "Disable wiping the console in watch mode",
              "type": "boolean",
              "markdownDescription": "Disable wiping the console in watch mode\n\nSee more: https://www.typescriptlang.org/tsconfig#preserveWatchOutput"
            },
            "pretty": {
              "description": "Enable color and formatting in output to make compiler errors easier to read",
              "type": "boolean",
              "default": true,
              "markdownDescription": "Enable color and formatting in output to make compiler errors easier to read\n\nSee more: https://www.typescriptlang.org/tsconfig#pretty"
            },
            "removeComments": {
              "description": "Disable emitting comments.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disable emitting comments.\n\nSee more: https://www.typescriptlang.org/tsconfig#removeComments"
            },
            "rootDir": {
              "description": "Specify the root folder within your source files.",
              "type": "string",
              "markdownDescription": "Specify the root folder within your source files.\n\nSee more: https://www.typescriptlang.org/tsconfig#rootDir"
            },
            "isolatedModules": {
              "description": "Ensure that each file can be safely transpiled without relying on other imports.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Ensure that each file can be safely transpiled without relying on other imports.\n\nSee more: https://www.typescriptlang.org/tsconfig#isolatedModules"
            },
            "sourceMap": {
              "description": "Create source map files for emitted JavaScript files.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Create source map files for emitted JavaScript files.\n\nSee more: https://www.typescriptlang.org/tsconfig#sourceMap"
            },
            "sourceRoot": {
              "description": "Specify the root path for debuggers to find the reference source code.",
              "type": "string",
              "markdownDescription": "Specify the root path for debuggers to find the reference source code.\n\nSee more: https://www.typescriptlang.org/tsconfig#sourceRoot"
            },
            "suppressExcessPropertyErrors": {
              "description": "Disable reporting of excess property errors during the creation of object literals.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disable reporting of excess property errors during the creation of object literals.\n\nSee more: https://www.typescriptlang.org/tsconfig#suppressExcessPropertyErrors"
            },
            "suppressImplicitAnyIndexErrors": {
              "description": "Suppress `noImplicitAny` errors when indexing objects that lack index signatures.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Suppress `noImplicitAny` errors when indexing objects that lack index signatures.\n\nSee more: https://www.typescriptlang.org/tsconfig#suppressImplicitAnyIndexErrors"
            },
            "stripInternal": {
              "description": "Disable emitting declarations that have `@internal` in their JSDoc comments.",
              "type": "boolean",
              "markdownDescription": "Disable emitting declarations that have `@internal` in their JSDoc comments.\n\nSee more: https://www.typescriptlang.org/tsconfig#stripInternal"
            },
            "target": {
              "description": "Set the JavaScript language version for emitted JavaScript and include compatible library declarations.",
              "type": "string",
              "default": "ES3",
              "anyOf": [
                {
                  "enum": [
                    "ES3",
                    "ES5",
                    "ES6",
                    "ES2015",
                    "ES2016",
                    "ES2017",
                    "ES2018",
                    "ES2019",
                    "ES2020",
                    "ESNext"
                  ]
                },
                {
                  "pattern": "^([Ee][Ss]([356]|(20(1[56789]|20))|[Nn][Ee][Xx][Tt]))$"
                }
              ],
              "markdownDescription": "Set the JavaScript language version for emitted JavaScript and include compatible library declarations.\n\nSee more: https://www.typescriptlang.org/tsconfig#target"
            },
            "watch": {
              "description": "Watch input files.",
              "type": "boolean"
            },
            "fallbackPolling": {
              "description": "Specify what approach the watcher should use if the system runs out of native file watchers.",
              "enum": [
                "fixedPollingInterval",
                "priorityPollingInterval",
                "dynamicPriorityPolling"
              ]
            },
            "watchDirectory": {
              "description": "Specify how directories are watched on systems that lack recursive file-watching functionality.",
              "enum": [
                "useFsEvents",
                "fixedPollingInterval",
                "dynamicPriorityPolling"
              ],
              "default": "useFsEvents"
            },
            "watchFile": {
              "description": "Specify how the TypeScript watch mode works.",
              "enum": [
                "fixedPollingInterval",
                "priorityPollingInterval",
                "dynamicPriorityPolling",
                "useFsEvents",
                "useFsEventsOnParentDirectory"
              ],
              "default": "useFsEvents"
            },
            "experimentalDecorators": {
              "description": "Enable experimental support for TC39 stage 2 draft decorators.",
              "type": "boolean",
              "markdownDescription": "Enable experimental support for TC39 stage 2 draft decorators.\n\nSee more: https://www.typescriptlang.org/tsconfig#experimentalDecorators"
            },
            "emitDecoratorMetadata": {
              "description": "Emit design-type metadata for decorated declarations in source files.",
              "type": "boolean",
              "markdownDescription": "Emit design-type metadata for decorated declarations in source files.\n\nSee more: https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata"
            },
            "allowUnusedLabels": {
              "description": "Disable error reporting for unused labels.",
              "type": "boolean",
              "markdownDescription": "Disable error reporting for unused labels.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowUnusedLabels"
            },
            "noImplicitReturns": {
              "description": "Enable error reporting for codepaths that do not explicitly return in a function.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Enable error reporting for codepaths that do not explicitly return in a function.\n\nSee more: https://www.typescriptlang.org/tsconfig#noImplicitReturns"
            },
            "noUncheckedIndexedAccess": {
              "description": "Add `undefined` to a type when accessed using an index.",
              "type": "boolean",
              "markdownDescription": "Add `undefined` to a type when accessed using an index.\n\nSee more: https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess"
            },
            "noFallthroughCasesInSwitch": {
              "description": "Enable error reporting for fallthrough cases in switch statements.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Enable error reporting for fallthrough cases in switch statements.\n\nSee more: https://www.typescriptlang.org/tsconfig#noFallthroughCasesInSwitch"
            },
            "allowUnreachableCode": {
              "description": "Disable error reporting for unreachable code.",
              "type": "boolean",
              "markdownDescription": "Disable error reporting for unreachable code.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowUnreachableCode"
            },
            "forceConsistentCasingInFileNames": {
              "description": "Ensure that casing is correct in imports.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Ensure that casing is correct in imports.\n\nSee more: https://www.typescriptlang.org/tsconfig#forceConsistentCasingInFileNames"
            },
            "generateCpuProfile": {
              "description": "Emit a v8 CPU profile of the compiler run for debugging.",
              "type": "string",
              "default": "profile.cpuprofile",
              "markdownDescription": "Emit a v8 CPU profile of the compiler run for debugging.\n\nSee more: https://www.typescriptlang.org/tsconfig#generateCpuProfile"
            },
            "baseUrl": {
              "description": "Specify the base directory to resolve non-relative module names.",
              "type": "string",
              "markdownDescription": "Specify the base directory to resolve non-relative module names.\n\nSee more: https://www.typescriptlang.org/tsconfig#baseUrl"
            },
            "paths": {
              "description": "Specify a set of entries that re-map imports to additional lookup locations.",
              "type": "object",
              "additionalProperties": {
                "type": "array",
                "uniqueItems": true,
                "items": {
                  "type": "string",
                  "description": "Path mapping to be computed relative to baseUrl option."
                }
              },
              "markdownDescription": "Specify a set of entries that re-map imports to additional lookup locations.\n\nSee more: https://www.typescriptlang.org/tsconfig#paths"
            },
            "plugins": {
              "description": "Specify a list of language service plugins to include.",
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "description": "Plugin name.",
                    "type": "string"
                  }
                }
              },
              "markdownDescription": "Specify a list of language service plugins to include.\n\nSee more: https://www.typescriptlang.org/tsconfig#plugins"
            },
            "rootDirs": {
              "description": "Allow multiple folders to be treated as one when resolving modules.",
              "type": "array",
              "uniqueItems": true,
              "items": {
                "type": "string"
              },
              "markdownDescription": "Allow multiple folders to be treated as one when resolving modules.\n\nSee more: https://www.typescriptlang.org/tsconfig#rootDirs"
            },
            "typeRoots": {
              "description": "Specify multiple folders that act like `./node_modules/@types`.",
              "type": "array",
              "uniqueItems": true,
              "items": {
                "type": "string"
              },
              "markdownDescription": "Specify multiple folders that act like `./node_modules/@types`.\n\nSee more: https://www.typescriptlang.org/tsconfig#typeRoots"
            },
            "types": {
              "description": "Specify type package names to be included without being referenced in a source file.",
              "type": "array",
              "uniqueItems": true,
              "items": {
                "type": "string"
              },
              "markdownDescription": "Specify type package names to be included without being referenced in a source file.\n\nSee more: https://www.typescriptlang.org/tsconfig#types"
            },
            "traceResolution": {
              "description": "Log paths used during the `moduleResolution` process.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Log paths used during the `moduleResolution` process.\n\nSee more: https://www.typescriptlang.org/tsconfig#traceResolution"
            },
            "allowJs": {
              "description": "Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowJs"
            },
            "noErrorTruncation": {
              "description": "Disable truncating types in error messages.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disable truncating types in error messages.\n\nSee more: https://www.typescriptlang.org/tsconfig#noErrorTruncation"
            },
            "allowSyntheticDefaultImports": {
              "description": "Allow 'import x from y' when a module doesn't have a default export.",
              "type": "boolean",
              "markdownDescription": "Allow 'import x from y' when a module doesn't have a default export.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowSyntheticDefaultImports"
            },
            "noImplicitUseStrict": {
              "description": "Disable adding 'use strict' directives in emitted JavaScript files.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Disable adding 'use strict' directives in emitted JavaScript files.\n\nSee more: https://www.typescriptlang.org/tsconfig#noImplicitUseStrict"
            },
            "listEmittedFiles": {
              "description": "Print the names of emitted files after a compilation.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Print the names of emitted files after a compilation.\n\nSee more: https://www.typescriptlang.org/tsconfig#listEmittedFiles"
            },
            "disableSizeLimit": {
              "description": "Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server.\n\nSee more: https://www.typescriptlang.org/tsconfig#disableSizeLimit"
            },
            "lib": {
              "description": "Specify a set of bundled library declaration files that describe the target runtime environment.",
              "type": "array",
              "uniqueItems": true,
              "items": {
                "type": "string",
                "anyOf": [
                  {
                    "enum": [
                      "ES5",
                      "ES6",
                      "ES2015",
                      "ES2015.Collection",
                      "ES2015.Core",
                      "ES2015.Generator",
                      "ES2015.Iterable",
                      "ES2015.Promise",
                      "ES2015.Proxy",
                      "ES2015.Reflect",
                      "ES2015.Symbol.WellKnown",
                      "ES2015.Symbol",
                      "ES2016",
                      "ES2016.Array.Include",
                      "ES2017",
                      "ES2017.Intl",
                      "ES2017.Object",
                      "ES2017.SharedMemory",
                      "ES2017.String",
                      "ES2017.TypedArrays",
                      "ES2018",
                      "ES2018.AsyncGenerator",
                      "ES2018.AsyncIterable",
                      "ES2018.Intl",
                      "ES2018.Promise",
                      "ES2018.Regexp",
                      "ES2019",
                      "ES2019.Array",
                      "ES2019.Object",
                      "ES2019.String",
                      "ES2019.Symbol",
                      "ES2020",
                      "ES2020.BigInt",
                      "ES2020.Promise",
                      "ES2020.String",
                      "ES2020.Symbol.WellKnown",
                      "ESNext",
                      "ESNext.Array",
                      "ESNext.AsyncIterable",
                      "ESNext.BigInt",
                      "ESNext.Intl",
                      "ESNext.Promise",
                      "ESNext.String",
                      "ESNext.Symbol",
                      "DOM",
                      "DOM.Iterable",
                      "ScriptHost",
                      "WebWorker",
                      "WebWorker.ImportScripts"
                    ]
                  },
                  {
                    "pattern": "^[Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]7$"
                  },
                  {
                    "pattern": "^[Ee][Ss]2015(\\.([Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Rr][Ee]|[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Pp][Rr][Oo][Xx][Yy]|[Rr][Ee][Ff][Ll][Ee][Cc][Tt]|[Ss][Yy][Mm][Bb][Oo][Ll].[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"
                  },
                  {
                    "pattern": "^[Ee][Ss]2016(\\.[Aa][Rr][Rr][Aa][Yy].[Ii][Nn][Cc][Ll][Uu][Dd][Ee])?$"
                  },
                  {
                    "pattern": "^[Ee][Ss]2017(\\.([Ii][Nn][Tt][Ll]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]))?$"
                  },
                  {
                    "pattern": "^[Ee][Ss]2018(\\.([Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ii][Nn][Tt][Ll]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Rr][Ee][Gg][Ee][Xx][Pp]))?$"
                  },
                  {
                    "pattern": "^[Ee][Ss]2019(\\.([Aa][Rr][Rr][Aa][Yy]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"
                  },
                  {
                    "pattern": "^[Ee][Ss]2020(\\.([Bb][Ii][Gg][Ii][Nn][Tt]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll].[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]))?$"
                  },
                  {
                    "pattern": "^[Ee][Ss][Nn][Ee][Xx][Tt](\\.([Aa][Rr][Rr][Aa][Yy]|[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Bb][Ii][Gg][Ii][Nn][Tt]|[Ii][Nn][Tt][Ll]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"
                  },
                  {
                    "pattern": "^[Dd][Oo][Mm](\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee])?$"
                  },
                  {
                    "pattern": "^[Ss][Cc][Rr][Ii][Pp][Tt][Hh][Oo][Ss][Tt]$"
                  },
                  {
                    "pattern": "^[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr](\\.[Ii][Mm][Pp][Oo][Rr][Tt][Ss][Cc][Rr][Ii][Pp][Tt][Ss])?$"
                  }
                ]
              },
              "markdownDescription": "Specify a set of bundled library declaration files that describe the target runtime environment.\n\nSee more: https://www.typescriptlang.org/tsconfig#lib"
            },
            "strictNullChecks": {
              "description": "When type checking, take into account `null` and `undefined`.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "When type checking, take into account `null` and `undefined`.\n\nSee more: https://www.typescriptlang.org/tsconfig#strictNullChecks"
            },
            "maxNodeModuleJsDepth": {
              "description": "Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`.",
              "type": "number",
              "default": 0,
              "markdownDescription": "Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`.\n\nSee more: https://www.typescriptlang.org/tsconfig#maxNodeModuleJsDepth"
            },
            "importHelpers": {
              "description": "Allow importing helper functions from tslib once per project, instead of including them per-file.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Allow importing helper functions from tslib once per project, instead of including them per-file.\n\nSee more: https://www.typescriptlang.org/tsconfig#importHelpers"
            },
            "importsNotUsedAsValues": {
              "description": "Specify emit/checking behavior for imports that are only used for types.",
              "default": "remove",
              "enum": ["remove", "preserve", "error"]
            },
            "alwaysStrict": {
              "description": "Ensure 'use strict' is always emitted.",
              "type": "boolean",
              "markdownDescription": "Ensure 'use strict' is always emitted.\n\nSee more: https://www.typescriptlang.org/tsconfig#alwaysStrict"
            },
            "strict": {
              "description": "Enable all strict type checking options.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Enable all strict type checking options.\n\nSee more: https://www.typescriptlang.org/tsconfig#strict"
            },
            "strictBindCallApply": {
              "description": "Check that the arguments for `bind`, `call`, and `apply` methods match the original function.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Check that the arguments for `bind`, `call`, and `apply` methods match the original function.\n\nSee more: https://www.typescriptlang.org/tsconfig#strictBindCallApply"
            },
            "downlevelIteration": {
              "description": "Emit more compliant, but verbose and less performant JavaScript for iteration.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Emit more compliant, but verbose and less performant JavaScript for iteration.\n\nSee more: https://www.typescriptlang.org/tsconfig#downlevelIteration"
            },
            "checkJs": {
              "description": "Enable error reporting in type-checked JavaScript files.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Enable error reporting in type-checked JavaScript files.\n\nSee more: https://www.typescriptlang.org/tsconfig#checkJs"
            },
            "strictFunctionTypes": {
              "description": "When assigning functions, check to ensure parameters and the return values are subtype-compatible.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "When assigning functions, check to ensure parameters and the return values are subtype-compatible.\n\nSee more: https://www.typescriptlang.org/tsconfig#strictFunctionTypes"
            },
            "strictPropertyInitialization": {
              "description": "Check for class properties that are declared but not set in the constructor.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Check for class properties that are declared but not set in the constructor.\n\nSee more: https://www.typescriptlang.org/tsconfig#strictPropertyInitialization"
            },
            "esModuleInterop": {
              "description": "Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility.\n\nSee more: https://www.typescriptlang.org/tsconfig#esModuleInterop"
            },
            "allowUmdGlobalAccess": {
              "description": "Allow accessing UMD globals from modules.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Allow accessing UMD globals from modules.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowUmdGlobalAccess"
            },
            "keyofStringsOnly": {
              "description": "Make keyof only return strings instead of string, numbers or symbols. Legacy option.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Make keyof only return strings instead of string, numbers or symbols. Legacy option.\n\nSee more: https://www.typescriptlang.org/tsconfig#keyofStringsOnly"
            },
            "useDefineForClassFields": {
              "description": "Emit ECMAScript-standard-compliant class fields.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Emit ECMAScript-standard-compliant class fields.\n\nSee more: https://www.typescriptlang.org/tsconfig#useDefineForClassFields"
            },
            "declarationMap": {
              "description": "Create sourcemaps for d.ts files.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Create sourcemaps for d.ts files.\n\nSee more: https://www.typescriptlang.org/tsconfig#declarationMap"
            },
            "resolveJsonModule": {
              "description": "Enable importing .json files",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Enable importing .json files\n\nSee more: https://www.typescriptlang.org/tsconfig#resolveJsonModule"
            },
            "assumeChangesOnlyAffectDirectDependencies": {
              "description": "Have recompiles in projects that use `incremental` and `watch` mode assume that changes within a file will only affect files directly depending on it.",
              "type": "boolean",
              "markdownDescription": "Have recompiles in projects that use `incremental` and `watch` mode assume that changes within a file will only affect files directly depending on it.\n\nSee more: https://www.typescriptlang.org/tsconfig#assumeChangesOnlyAffectDirectDependencies"
            },
            "extendedDiagnostics": {
              "description": "Output more detailed compiler performance information after building.",
              "type": "boolean",
              "default": false,
              "markdownDescription": "Output more detailed compiler performance information after building.\n\nSee more: https://www.typescriptlang.org/tsconfig#extendedDiagnostics"
            },
            "listFilesOnly": {
              "description": "Print names of files that are part of the compilation and then stop processing.",
              "type": "boolean"
            },
            "disableSourceOfProjectReferenceRedirect": {
              "description": "Disable preferring source files instead of declaration files when referencing composite projects",
              "type": "boolean",
              "markdownDescription": "Disable preferring source files instead of declaration files when referencing composite projects\n\nSee more: https://www.typescriptlang.org/tsconfig#disableSourceOfProjectReferenceRedirect"
            },
            "disableSolutionSearching": {
              "description": "Opt a project out of multi-project reference checking when editing.",
              "type": "boolean",
              "markdownDescription": "Opt a project out of multi-project reference checking when editing.\n\nSee more: https://www.typescriptlang.org/tsconfig#disableSolutionSearching"
            }
          }
        }
      }
    },
    "typeAcquisitionDefinition": {
      "properties": {
        "typeAcquisition": {
          "type": "object",
          "description": "Auto type (.d.ts) acquisition options for this project. Requires TypeScript version 2.1 or later.",
          "properties": {
            "enable": {
              "description": "Enable auto type acquisition",
              "type": "boolean",
              "default": false
            },
            "include": {
              "description": "Specifies a list of type declarations to be included in auto type acquisition. Ex. [\"jquery\", \"lodash\"]",
              "type": "array",
              "uniqueItems": true,
              "items": {
                "type": "string"
              }
            },
            "exclude": {
              "description": "Specifies a list of type declarations to be excluded from auto type acquisition. Ex. [\"jquery\", \"lodash\"]",
              "type": "array",
              "uniqueItems": true,
              "items": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "referencesDefinition": {
      "properties": {
        "references": {
          "type": "array",
          "uniqueItems": true,
          "description": "Referenced projects. Requires TypeScript version 3.0 or later.",
          "items": {
            "type": "object",
            "description": "Project reference.",
            "properties": {
              "path": {
                "type": "string",
                "description": "Path to referenced tsconfig or to folder containing tsconfig."
              }
            }
          }
        }
      }
    },
    "tsNodeDefinition": {
      "properties": {
        "ts-node": {
          "description": "ts-node options.  See also: https://github.com/TypeStrong/ts-node#configuration-options\n\nts-node offers TypeScript execution and REPL for node.js, with source map support.",
          "properties": {
            "compiler": {
              "default": "typescript",
              "description": "Specify a custom TypeScript compiler.",
              "type": "string"
            },
            "compilerHost": {
              "default": false,
              "description": "Use TypeScript's compiler host API.",
              "type": "boolean"
            },
            "compilerOptions": {
              "additionalProperties": true,
              "allOf": [
                {
                  "$ref": "#/definitions/compilerOptionsDefinition/properties/compilerOptions"
                }
              ],
              "description": "JSON object to merge with compiler options.",
              "properties": {},
              "type": "object"
            },
            "emit": {
              "default": false,
              "description": "Emit output files into `.ts-node` directory.",
              "type": "boolean"
            },
            "files": {
              "default": false,
              "description": "Load files from `tsconfig.json` on startup.",
              "type": "boolean"
            },
            "ignore": {
              "default": "/node_modules/",
              "description": "Override the path patterns to skip compilation.",
              "items": {
                "type": "string"
              },
              "type": "array",
              "uniqueItems": true
            },
            "ignoreDiagnostics": {
              "description": "Ignore TypeScript warnings by diagnostic code.",
              "items": {
                "type": ["string", "number"]
              },
              "type": "array",
              "uniqueItems": true
            },
            "logError": {
              "default": false,
              "description": "Logs TypeScript errors to stderr instead of throwing exceptions.",
              "type": "boolean"
            },
            "preferTsExts": {
              "default": false,
              "description": "Re-order file extensions so that TypeScript imports are preferred.",
              "type": "boolean"
            },
            "pretty": {
              "default": false,
              "description": "Use pretty diagnostic formatter.",
              "type": "boolean"
            },
            "require": {
              "description": "Modules to require, like node's `--require` flag.\n\nIf specified in tsconfig.json, the modules will be resolved relative to the tsconfig.json file.\n\nIf specified programmatically, each input string should be pre-resolved to an absolute path for\nbest results.",
              "items": {
                "type": "string"
              },
              "type": "array",
              "uniqueItems": true
            },
            "scope": {
              "default": false,
              "description": "Scope compiler to files within `cwd`.",
              "type": "boolean"
            },
            "skipIgnore": {
              "default": false,
              "description": "Skip ignore check.",
              "type": "boolean"
            },
            "transpileOnly": {
              "default": false,
              "description": "Use TypeScript's faster `transpileModule`.",
              "type": "boolean"
            },
            "typeCheck": {
              "default": true,
              "description": "**DEPRECATED** Specify type-check is enabled (e.g. `transpileOnly == false`).",
              "type": "boolean"
            }
          },
          "type": "object"
        }
      }
    }
  },
  "type": "object",
  "allOf": [
    {
      "$ref": "#/definitions/compilerOptionsDefinition"
    },
    {
      "$ref": "#/definitions/compileOnSaveDefinition"
    },
    {
      "$ref": "#/definitions/typeAcquisitionDefinition"
    },
    {
      "$ref": "#/definitions/extendsDefinition"
    },
    {
      "$ref": "#/definitions/tsNodeDefinition"
    },
    {
      "anyOf": [
        {
          "$ref": "#/definitions/filesDefinition"
        },
        {
          "$ref": "#/definitions/excludeDefinition"
        },
        {
          "$ref": "#/definitions/includeDefinition"
        },
        {
          "$ref": "#/definitions/referencesDefinition"
        }
      ]
    }
  ]
}
{
  "title": "JSON schema for the TypeScript compiler's configuration file",
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "https://json.schemastore.org/tsconfig",
  "definitions": {
    "//": {
      "explainer": "https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#overview",
      "reference": "https://www.typescriptlang.org/tsconfig",
      "reference metadata": "https://github.com/microsoft/TypeScript-Website/blob/v2/packages/tsconfig-reference/scripts/tsconfigRules.ts"
    },
    "filesDefinition": {...},
    "excludeDefinition": {...},
    "includeDefinition": {...},
    "compileOnSaveDefinition": {...},
    "extendsDefinition": {...},
    "compilerOptionsDefinition": {...},
    "typeAcquisitionDefinition": {...},
    "referencesDefinition": {...},
    "tsNodeDefinition": {...}
  },
  "type": "object",
  "allOf": [
    {
      "$ref": "#/definitions/compilerOptionsDefinition"
    },
    {
      "$ref": "#/definitions/compileOnSaveDefinition"
    },
    {
      "$ref": "#/definitions/typeAcquisitionDefinition"
    },
    {
      "$ref": "#/definitions/extendsDefinition"
    },
    {
      "$ref": "#/definitions/tsNodeDefinition"
    },
    {
      "anyOf": [
        {
          "$ref": "#/definitions/filesDefinition"
        },
        {
          "$ref": "#/definitions/excludeDefinition"
        },
        {
          "$ref": "#/definitions/includeDefinition"
        },
        {
          "$ref": "#/definitions/referencesDefinition"
        }
      ]
    }
  ]
}

최상위 프로퍼티

  • compileOnSave

  • extends

  • compileOptions

  • files

  • include

  • exclude

  • references

  • typeAcquisition

  • tsNode

compileOnSave

{
  ...,
  "compileOnSaveDefinition": {
    "properties": {
      "compileOnSave": {
        "description": "Enable Compile-on-Save for this project.",
        "type": "boolean"
      }
    }
  },
  ...,
}

compileOnSave

extends

{
  ...,
  "extendsDefinition": {
    "properties": {
      "extends": {
        "description": "Path to base configuration file to inherit from. Requires TypeScript version 2.1 or later.",
        "type": "string"
      }
    }
  },
  ...,
}

extends

  • 파일 (상대) 경로명: string

  • TypeScript 2.1 New Spec

// in PROJECT/base.json
{
  "compilerOptions": {
    "strict": true
  }
}


// in PROJECT/tsconfig.json
{
  "extends": "./base.json",
}

npm install --save-dev @tsconfig/deno

{
  "extends": "@tsconfig/deno/tsconfig.json",
  ...
}

files, include, exclude

{
  ...,
  "filesDefinition": {
    "properties": {
      "files": {
        "description": "If no 'files' or 'include' property is present in a tsconfig.json, the compiler defaults to including all files in the containing directory and subdirectories except those specified by 'exclude'. When a 'files' property is specified, only those files and those specified by 'include' are included.",
        "type": "array",
        "uniqueItems": true,
        "items": {
          "type": "string"
        }
      }
    }
  },
  "excludeDefinition": {
    "properties": {
      "exclude": {
        "description": "Specifies a list of files to be excluded from compilation. The 'exclude' property only affects the files included via the 'include' property and not the 'files' property. Glob patterns require TypeScript version 2.0 or later.",
        "type": "array",
        "uniqueItems": true,
        "items": {
          "type": "string"
        }
      }
    }
  },
  "includeDefinition": {
    "properties": {
      "include": {
        "description": "Specifies a list of glob patterns that match files to be included in compilation. If no 'files' or 'include' property is present in a tsconfig.json, the compiler defaults to including all files in the containing directory and subdirectories except those specified by 'exclude'. Requires TypeScript version 2.0 or later.",
        "type": "array",
        "uniqueItems": true,
        "items": {
          "type": "string"
        }
      }
    }
  },
  ...,
}

files, include, exclude

  • 셋다 설정이 없으면, 전부다 컴파일

  • files

    • 상대 혹은 절대 경로의 리스트 배열입니다.

    • exclude 보다 쎕니다.

  • include, exclude

    • glob 패턴 (마치 .gitignore)

    • include

      • exclude 보다 약합니다.

      • * 같은걸 사용하면, .ts / .tsx / .d.ts 만 include (allowJS)

    • exclude

      • 설정 안하면 4가지(node_modules, bower_components, jspm_packages, <outDir>)를 default 로 제외합니다.

      • <outDir> 은 항상 제외합니다. (include 에 있어도)

compileOptions

- typeRoots, types

{
  ...,
  "compilerOptionsDefinition":{
    "properties":{
      "compilerOptions":{
        "type":"object",
        "description":"Instructs the TypeScript compiler how to compile .ts files.",
        "properties":{
          "charset":{
            "description":"No longer supported. In early versions, manually set the text encoding for reading files.",
            "type":"string",
            "markdownDescription":"No longer supported. In early versions, manually set the text encoding for reading files.\n\nSee more: https://www.typescriptlang.org/tsconfig#charset"
          },
          "composite":{
            "description":"Enable constraints that allow a TypeScript project to be used with project references.",
            "type":"boolean",
            "default":true,
            "markdownDescription":"Enable constraints that allow a TypeScript project to be used with project references.\n\nSee more: https://www.typescriptlang.org/tsconfig#composite"
          },
          "declaration":{
            "description":"Generate .d.ts files from TypeScript and JavaScript files in your project.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Generate .d.ts files from TypeScript and JavaScript files in your project.\n\nSee more: https://www.typescriptlang.org/tsconfig#declaration"
          },
          "declarationDir":{
            "description":"Specify the output directory for generated declaration files.",
            "type":[
              "string",
              "null"
            ],
            "markdownDescription":"Specify the output directory for generated declaration files.\n\nSee more: https://www.typescriptlang.org/tsconfig#declarationDir"
          },
          "diagnostics":{
            "description":"Output compiler performance information after building.",
            "type":"boolean",
            "markdownDescription":"Output compiler performance information after building.\n\nSee more: https://www.typescriptlang.org/tsconfig#diagnostics"
          },
          "disableReferencedProjectLoad":{
            "description":"Reduce the number of projects loaded automatically by TypeScript.",
            "type":"boolean",
            "markdownDescription":"Reduce the number of projects loaded automatically by TypeScript.\n\nSee more: https://www.typescriptlang.org/tsconfig#disableReferencedProjectLoad"
          },
          "noPropertyAccessFromIndexSignature":{
            "description":"Enforces using indexed accessors for keys declared using an indexed type",
            "type":"boolean",
            "markdownDescription":"Enforces using indexed accessors for keys declared using an indexed type\n\nSee more: https://www.typescriptlang.org/tsconfig#noPropertyAccessFromIndexSignature"
          },
          "emitBOM":{
            "description":"Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.\n\nSee more: https://www.typescriptlang.org/tsconfig#emitBOM"
          },
          "emitDeclarationOnly":{
            "description":"Only output d.ts files and not JavaScript files.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Only output d.ts files and not JavaScript files.\n\nSee more: https://www.typescriptlang.org/tsconfig#emitDeclarationOnly"
          },
          "incremental":{
            "description":"Save .tsbuildinfo files to allow for incremental compilation of projects.",
            "type":"boolean",
            "markdownDescription":"Save .tsbuildinfo files to allow for incremental compilation of projects.\n\nSee more: https://www.typescriptlang.org/tsconfig#incremental"
          },
          "tsBuildInfoFile":{
            "description":"Specify the folder for .tsbuildinfo incremental compilation files.",
            "default":".tsbuildinfo",
            "type":"string",
            "markdownDescription":"Specify the folder for .tsbuildinfo incremental compilation files.\n\nSee more: https://www.typescriptlang.org/tsconfig#tsBuildInfoFile"
          },
          "inlineSourceMap":{
            "description":"Include sourcemap files inside the emitted JavaScript.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Include sourcemap files inside the emitted JavaScript.\n\nSee more: https://www.typescriptlang.org/tsconfig#inlineSourceMap"
          },
          "inlineSources":{
            "description":"Include source code in the sourcemaps inside the emitted JavaScript.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Include source code in the sourcemaps inside the emitted JavaScript.\n\nSee more: https://www.typescriptlang.org/tsconfig#inlineSources"
          },
          "jsx":{
            "description":"Specify what JSX code is generated.",
            "enum":[
              "preserve",
              "react",
              "react-jsx",
              "react-jsxdev",
              "react-native"
            ]
          },
          "reactNamespace":{
            "description":"Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit.",
            "type":"string",
            "default":"React",
            "markdownDescription":"Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit.\n\nSee more: https://www.typescriptlang.org/tsconfig#reactNamespace"
          },
          "jsxFactory":{
            "description":"Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'",
            "type":"string",
            "default":"React.createElement",
            "markdownDescription":"Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'\n\nSee more: https://www.typescriptlang.org/tsconfig#jsxFactory"
          },
          "jsxFragmentFactory":{
            "description":"Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'.",
            "type":"string",
            "default":"React.Fragment",
            "markdownDescription":"Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'.\n\nSee more: https://www.typescriptlang.org/tsconfig#jsxFragmentFactory"
          },
          "jsxImportSource":{
            "description":"Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.`",
            "type":"string",
            "default":"react",
            "markdownDescription":"Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.`\n\nSee more: https://www.typescriptlang.org/tsconfig#jsxImportSource"
          },
          "listFiles":{
            "description":"Print all of the files read during the compilation.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Print all of the files read during the compilation.\n\nSee more: https://www.typescriptlang.org/tsconfig#listFiles"
          },
          "mapRoot":{
            "description":"Specify the location where debugger should locate map files instead of generated locations.",
            "type":"string",
            "markdownDescription":"Specify the location where debugger should locate map files instead of generated locations.\n\nSee more: https://www.typescriptlang.org/tsconfig#mapRoot"
          },
          "module":{
            "description":"Specify what module code is generated.",
            "type":"string",
            "anyOf":[
              {
                "enum":[
                  "CommonJS",
                  "AMD",
                  "System",
                  "UMD",
                  "ES6",
                  "ES2015",
                  "ES2020",
                  "ESNext",
                  "None"
                ]
              },
              {
                "pattern":"^([Cc][Oo][Mm][Mm][Oo][Nn][Jj][Ss]|[AaUu][Mm][Dd]|[Ss][Yy][Ss][Tt][Ee][Mm]|[Ee][Ss]([356]|201[567]|2020|[Nn][Ee][Xx][Tt])|[Nn][Oo][Nn][Ee])$"
              }
            ],
            "markdownDescription":"Specify what module code is generated.\n\nSee more: https://www.typescriptlang.org/tsconfig#module"
          },
          "moduleResolution":{
            "description":"Specify how TypeScript looks up a file from a given module specifier.",
            "type":"string",
            "anyOf":[
              {
                "enum":[
                  "Classic",
                  "Node"
                ]
              },
              {
                "pattern":"^(([Nn]ode)|([Cc]lassic))$"
              }
            ],
            "default":"classic",
            "markdownDescription":"Specify how TypeScript looks up a file from a given module specifier.\n\nSee more: https://www.typescriptlang.org/tsconfig#moduleResolution"
          },
          "newLine":{
            "description":"Set the newline character for emitting files.",
            "type":"string",
            "anyOf":[
              {
                "enum":[
                  "crlf",
                  "lf"
                ]
              },
              {
                "pattern":"^(CRLF|LF|crlf|lf)$"
              }
            ],
            "markdownDescription":"Set the newline character for emitting files.\n\nSee more: https://www.typescriptlang.org/tsconfig#newLine"
          },
          "noEmit":{
            "description":"Disable emitting file from a compilation.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disable emitting file from a compilation.\n\nSee more: https://www.typescriptlang.org/tsconfig#noEmit"
          },
          "noEmitHelpers":{
            "description":"Disable generating custom helper functions like `__extends` in compiled output.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disable generating custom helper functions like `__extends` in compiled output.\n\nSee more: https://www.typescriptlang.org/tsconfig#noEmitHelpers"
          },
          "noEmitOnError":{
            "description":"Disable emitting files if any type checking errors are reported.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disable emitting files if any type checking errors are reported.\n\nSee more: https://www.typescriptlang.org/tsconfig#noEmitOnError"
          },
          "noImplicitAny":{
            "description":"Enable error reporting for expressions and declarations with an implied `any` type..",
            "type":"boolean",
            "markdownDescription":"Enable error reporting for expressions and declarations with an implied `any` type..\n\nSee more: https://www.typescriptlang.org/tsconfig#noImplicitAny"
          },
          "noImplicitThis":{
            "description":"Enable error reporting when `this` is given the type `any`.",
            "type":"boolean",
            "markdownDescription":"Enable error reporting when `this` is given the type `any`.\n\nSee more: https://www.typescriptlang.org/tsconfig#noImplicitThis"
          },
          "noUnusedLocals":{
            "description":"Enable error reporting when a local variables aren't read.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Enable error reporting when a local variables aren't read.\n\nSee more: https://www.typescriptlang.org/tsconfig#noUnusedLocals"
          },
          "noUnusedParameters":{
            "description":"Raise an error when a function parameter isn't read",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Raise an error when a function parameter isn't read\n\nSee more: https://www.typescriptlang.org/tsconfig#noUnusedParameters"
          },
          "noLib":{
            "description":"Disable including any library files, including the default lib.d.ts.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disable including any library files, including the default lib.d.ts.\n\nSee more: https://www.typescriptlang.org/tsconfig#noLib"
          },
          "noResolve":{
            "description":"Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project.\n\nSee more: https://www.typescriptlang.org/tsconfig#noResolve"
          },
          "noStrictGenericChecks":{
            "description":"Disable strict checking of generic signatures in function types.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disable strict checking of generic signatures in function types.\n\nSee more: https://www.typescriptlang.org/tsconfig#noStrictGenericChecks"
          },
          "skipDefaultLibCheck":{
            "description":"Skip type checking .d.ts files that are included with TypeScript.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Skip type checking .d.ts files that are included with TypeScript.\n\nSee more: https://www.typescriptlang.org/tsconfig#skipDefaultLibCheck"
          },
          "skipLibCheck":{
            "description":"Skip type checking all .d.ts files.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Skip type checking all .d.ts files.\n\nSee more: https://www.typescriptlang.org/tsconfig#skipLibCheck"
          },
          "outFile":{
            "description":"Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output.",
            "type":"string",
            "markdownDescription":"Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output.\n\nSee more: https://www.typescriptlang.org/tsconfig#outFile"
          },
          "outDir":{
            "description":"Specify an output folder for all emitted files.",
            "type":"string",
            "markdownDescription":"Specify an output folder for all emitted files.\n\nSee more: https://www.typescriptlang.org/tsconfig#outDir"
          },
          "preserveConstEnums":{
            "description":"Disable erasing `const enum` declarations in generated code.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disable erasing `const enum` declarations in generated code.\n\nSee more: https://www.typescriptlang.org/tsconfig#preserveConstEnums"
          },
          "preserveSymlinks":{
            "description":"Disable resolving symlinks to their realpath. This correlates to the same flag in node.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disable resolving symlinks to their realpath. This correlates to the same flag in node.\n\nSee more: https://www.typescriptlang.org/tsconfig#preserveSymlinks"
          },
          "preserveWatchOutput":{
            "description":"Disable wiping the console in watch mode",
            "type":"boolean",
            "markdownDescription":"Disable wiping the console in watch mode\n\nSee more: https://www.typescriptlang.org/tsconfig#preserveWatchOutput"
          },
          "pretty":{
            "description":"Enable color and formatting in output to make compiler errors easier to read",
            "type":"boolean",
            "default":true,
            "markdownDescription":"Enable color and formatting in output to make compiler errors easier to read\n\nSee more: https://www.typescriptlang.org/tsconfig#pretty"
          },
          "removeComments":{
            "description":"Disable emitting comments.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disable emitting comments.\n\nSee more: https://www.typescriptlang.org/tsconfig#removeComments"
          },
          "rootDir":{
            "description":"Specify the root folder within your source files.",
            "type":"string",
            "markdownDescription":"Specify the root folder within your source files.\n\nSee more: https://www.typescriptlang.org/tsconfig#rootDir"
          },
          "isolatedModules":{
            "description":"Ensure that each file can be safely transpiled without relying on other imports.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Ensure that each file can be safely transpiled without relying on other imports.\n\nSee more: https://www.typescriptlang.org/tsconfig#isolatedModules"
          },
          "sourceMap":{
            "description":"Create source map files for emitted JavaScript files.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Create source map files for emitted JavaScript files.\n\nSee more: https://www.typescriptlang.org/tsconfig#sourceMap"
          },
          "sourceRoot":{
            "description":"Specify the root path for debuggers to find the reference source code.",
            "type":"string",
            "markdownDescription":"Specify the root path for debuggers to find the reference source code.\n\nSee more: https://www.typescriptlang.org/tsconfig#sourceRoot"
          },
          "suppressExcessPropertyErrors":{
            "description":"Disable reporting of excess property errors during the creation of object literals.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disable reporting of excess property errors during the creation of object literals.\n\nSee more: https://www.typescriptlang.org/tsconfig#suppressExcessPropertyErrors"
          },
          "suppressImplicitAnyIndexErrors":{
            "description":"Suppress `noImplicitAny` errors when indexing objects that lack index signatures.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Suppress `noImplicitAny` errors when indexing objects that lack index signatures.\n\nSee more: https://www.typescriptlang.org/tsconfig#suppressImplicitAnyIndexErrors"
          },
          "stripInternal":{
            "description":"Disable emitting declarations that have `@internal` in their JSDoc comments.",
            "type":"boolean",
            "markdownDescription":"Disable emitting declarations that have `@internal` in their JSDoc comments.\n\nSee more: https://www.typescriptlang.org/tsconfig#stripInternal"
          },
          "target":{
            "description":"Set the JavaScript language version for emitted JavaScript and include compatible library declarations.",
            "type":"string",
            "default":"ES3",
            "anyOf":[
              {
                "enum":[
                  "ES3",
                  "ES5",
                  "ES6",
                  "ES2015",
                  "ES2016",
                  "ES2017",
                  "ES2018",
                  "ES2019",
                  "ES2020",
                  "ESNext"
                ]
              },
              {
                "pattern":"^([Ee][Ss]([356]|(20(1[56789]|20))|[Nn][Ee][Xx][Tt]))$"
              }
            ],
            "markdownDescription":"Set the JavaScript language version for emitted JavaScript and include compatible library declarations.\n\nSee more: https://www.typescriptlang.org/tsconfig#target"
          },
          "watch":{
            "description":"Watch input files.",
            "type":"boolean"
          },
          "fallbackPolling":{
            "description":"Specify what approach the watcher should use if the system runs out of native file watchers.",
            "enum":[
              "fixedPollingInterval",
              "priorityPollingInterval",
              "dynamicPriorityPolling"
            ]
          },
          "watchDirectory":{
            "description":"Specify how directories are watched on systems that lack recursive file-watching functionality.",
            "enum":[
              "useFsEvents",
              "fixedPollingInterval",
              "dynamicPriorityPolling"
            ],
            "default":"useFsEvents"
          },
          "watchFile":{
            "description":"Specify how the TypeScript watch mode works.",
            "enum":[
              "fixedPollingInterval",
              "priorityPollingInterval",
              "dynamicPriorityPolling",
              "useFsEvents",
              "useFsEventsOnParentDirectory"
            ],
            "default":"useFsEvents"
          },
          "experimentalDecorators":{
            "description":"Enable experimental support for TC39 stage 2 draft decorators.",
            "type":"boolean",
            "markdownDescription":"Enable experimental support for TC39 stage 2 draft decorators.\n\nSee more: https://www.typescriptlang.org/tsconfig#experimentalDecorators"
          },
          "emitDecoratorMetadata":{
            "description":"Emit design-type metadata for decorated declarations in source files.",
            "type":"boolean",
            "markdownDescription":"Emit design-type metadata for decorated declarations in source files.\n\nSee more: https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata"
          },
          "allowUnusedLabels":{
            "description":"Disable error reporting for unused labels.",
            "type":"boolean",
            "markdownDescription":"Disable error reporting for unused labels.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowUnusedLabels"
          },
          "noImplicitReturns":{
            "description":"Enable error reporting for codepaths that do not explicitly return in a function.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Enable error reporting for codepaths that do not explicitly return in a function.\n\nSee more: https://www.typescriptlang.org/tsconfig#noImplicitReturns"
          },
          "noUncheckedIndexedAccess":{
            "description":"Add `undefined` to a type when accessed using an index.",
            "type":"boolean",
            "markdownDescription":"Add `undefined` to a type when accessed using an index.\n\nSee more: https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess"
          },
          "noFallthroughCasesInSwitch":{
            "description":"Enable error reporting for fallthrough cases in switch statements.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Enable error reporting for fallthrough cases in switch statements.\n\nSee more: https://www.typescriptlang.org/tsconfig#noFallthroughCasesInSwitch"
          },
          "allowUnreachableCode":{
            "description":"Disable error reporting for unreachable code.",
            "type":"boolean",
            "markdownDescription":"Disable error reporting for unreachable code.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowUnreachableCode"
          },
          "forceConsistentCasingInFileNames":{
            "description":"Ensure that casing is correct in imports.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Ensure that casing is correct in imports.\n\nSee more: https://www.typescriptlang.org/tsconfig#forceConsistentCasingInFileNames"
          },
          "generateCpuProfile":{
            "description":"Emit a v8 CPU profile of the compiler run for debugging.",
            "type":"string",
            "default":"profile.cpuprofile",
            "markdownDescription":"Emit a v8 CPU profile of the compiler run for debugging.\n\nSee more: https://www.typescriptlang.org/tsconfig#generateCpuProfile"
          },
          "baseUrl":{
            "description":"Specify the base directory to resolve non-relative module names.",
            "type":"string",
            "markdownDescription":"Specify the base directory to resolve non-relative module names.\n\nSee more: https://www.typescriptlang.org/tsconfig#baseUrl"
          },
          "paths":{
            "description":"Specify a set of entries that re-map imports to additional lookup locations.",
            "type":"object",
            "additionalProperties":{
              "type":"array",
              "uniqueItems":true,
              "items":{
                "type":"string",
                "description":"Path mapping to be computed relative to baseUrl option."
              }
            },
            "markdownDescription":"Specify a set of entries that re-map imports to additional lookup locations.\n\nSee more: https://www.typescriptlang.org/tsconfig#paths"
          },
          "plugins":{
            "description":"Specify a list of language service plugins to include.",
            "type":"array",
            "items":{
              "type":"object",
              "properties":{
                "name":{
                  "description":"Plugin name.",
                  "type":"string"
                }
              }
            },
            "markdownDescription":"Specify a list of language service plugins to include.\n\nSee more: https://www.typescriptlang.org/tsconfig#plugins"
          },
          "rootDirs":{
            "description":"Allow multiple folders to be treated as one when resolving modules.",
            "type":"array",
            "uniqueItems":true,
            "items":{
              "type":"string"
            },
            "markdownDescription":"Allow multiple folders to be treated as one when resolving modules.\n\nSee more: https://www.typescriptlang.org/tsconfig#rootDirs"
          },
          "typeRoots":{
            "description":"Specify multiple folders that act like `./node_modules/@types`.",
            "type":"array",
            "uniqueItems":true,
            "items":{
              "type":"string"
            },
            "markdownDescription":"Specify multiple folders that act like `./node_modules/@types`.\n\nSee more: https://www.typescriptlang.org/tsconfig#typeRoots"
          },
          "types":{
            "description":"Specify type package names to be included without being referenced in a source file.",
            "type":"array",
            "uniqueItems":true,
            "items":{
              "type":"string"
            },
            "markdownDescription":"Specify type package names to be included without being referenced in a source file.\n\nSee more: https://www.typescriptlang.org/tsconfig#types"
          },
          "traceResolution":{
            "description":"Log paths used during the `moduleResolution` process.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Log paths used during the `moduleResolution` process.\n\nSee more: https://www.typescriptlang.org/tsconfig#traceResolution"
          },
          "allowJs":{
            "description":"Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowJs"
          },
          "noErrorTruncation":{
            "description":"Disable truncating types in error messages.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disable truncating types in error messages.\n\nSee more: https://www.typescriptlang.org/tsconfig#noErrorTruncation"
          },
          "allowSyntheticDefaultImports":{
            "description":"Allow 'import x from y' when a module doesn't have a default export.",
            "type":"boolean",
            "markdownDescription":"Allow 'import x from y' when a module doesn't have a default export.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowSyntheticDefaultImports"
          },
          "noImplicitUseStrict":{
            "description":"Disable adding 'use strict' directives in emitted JavaScript files.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Disable adding 'use strict' directives in emitted JavaScript files.\n\nSee more: https://www.typescriptlang.org/tsconfig#noImplicitUseStrict"
          },
          "listEmittedFiles":{
            "description":"Print the names of emitted files after a compilation.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Print the names of emitted files after a compilation.\n\nSee more: https://www.typescriptlang.org/tsconfig#listEmittedFiles"
          },
          "disableSizeLimit":{
            "description":"Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server.\n\nSee more: https://www.typescriptlang.org/tsconfig#disableSizeLimit"
          },
          "lib":{
            "description":"Specify a set of bundled library declaration files that describe the target runtime environment.",
            "type":"array",
            "uniqueItems":true,
            "items":{
              "type":"string",
              "anyOf":[
                {
                  "enum":[
                    "ES5",
                    "ES6",
                    "ES2015",
                    "ES2015.Collection",
                    "ES2015.Core",
                    "ES2015.Generator",
                    "ES2015.Iterable",
                    "ES2015.Promise",
                    "ES2015.Proxy",
                    "ES2015.Reflect",
                    "ES2015.Symbol.WellKnown",
                    "ES2015.Symbol",
                    "ES2016",
                    "ES2016.Array.Include",
                    "ES2017",
                    "ES2017.Intl",
                    "ES2017.Object",
                    "ES2017.SharedMemory",
                    "ES2017.String",
                    "ES2017.TypedArrays",
                    "ES2018",
                    "ES2018.AsyncGenerator",
                    "ES2018.AsyncIterable",
                    "ES2018.Intl",
                    "ES2018.Promise",
                    "ES2018.Regexp",
                    "ES2019",
                    "ES2019.Array",
                    "ES2019.Object",
                    "ES2019.String",
                    "ES2019.Symbol",
                    "ES2020",
                    "ES2020.BigInt",
                    "ES2020.Promise",
                    "ES2020.String",
                    "ES2020.Symbol.WellKnown",
                    "ESNext",
                    "ESNext.Array",
                    "ESNext.AsyncIterable",
                    "ESNext.BigInt",
                    "ESNext.Intl",
                    "ESNext.Promise",
                    "ESNext.String",
                    "ESNext.Symbol",
                    "DOM",
                    "DOM.Iterable",
                    "ScriptHost",
                    "WebWorker",
                    "WebWorker.ImportScripts"
                  ]
                },
                {
                  "pattern":"^[Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]7$"
                },
                {
                  "pattern":"^[Ee][Ss]2015(\\.([Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Rr][Ee]|[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Pp][Rr][Oo][Xx][Yy]|[Rr][Ee][Ff][Ll][Ee][Cc][Tt]|[Ss][Yy][Mm][Bb][Oo][Ll].[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"
                },
                {
                  "pattern":"^[Ee][Ss]2016(\\.[Aa][Rr][Rr][Aa][Yy].[Ii][Nn][Cc][Ll][Uu][Dd][Ee])?$"
                },
                {
                  "pattern":"^[Ee][Ss]2017(\\.([Ii][Nn][Tt][Ll]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]))?$"
                },
                {
                  "pattern":"^[Ee][Ss]2018(\\.([Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ii][Nn][Tt][Ll]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Rr][Ee][Gg][Ee][Xx][Pp]))?$"
                },
                {
                  "pattern":"^[Ee][Ss]2019(\\.([Aa][Rr][Rr][Aa][Yy]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"
                },
                {
                  "pattern":"^[Ee][Ss]2020(\\.([Bb][Ii][Gg][Ii][Nn][Tt]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll].[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]))?$"
                },
                {
                  "pattern":"^[Ee][Ss][Nn][Ee][Xx][Tt](\\.([Aa][Rr][Rr][Aa][Yy]|[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Bb][Ii][Gg][Ii][Nn][Tt]|[Ii][Nn][Tt][Ll]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"
                },
                {
                  "pattern":"^[Dd][Oo][Mm](\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee])?$"
                },
                {
                  "pattern":"^[Ss][Cc][Rr][Ii][Pp][Tt][Hh][Oo][Ss][Tt]$"
                },
                {
                  "pattern":"^[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr](\\.[Ii][Mm][Pp][Oo][Rr][Tt][Ss][Cc][Rr][Ii][Pp][Tt][Ss])?$"
                }
              ]
            },
            "markdownDescription":"Specify a set of bundled library declaration files that describe the target runtime environment.\n\nSee more: https://www.typescriptlang.org/tsconfig#lib"
          },
          "strictNullChecks":{
            "description":"When type checking, take into account `null` and `undefined`.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"When type checking, take into account `null` and `undefined`.\n\nSee more: https://www.typescriptlang.org/tsconfig#strictNullChecks"
          },
          "maxNodeModuleJsDepth":{
            "description":"Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`.",
            "type":"number",
            "default":0,
            "markdownDescription":"Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`.\n\nSee more: https://www.typescriptlang.org/tsconfig#maxNodeModuleJsDepth"
          },
          "importHelpers":{
            "description":"Allow importing helper functions from tslib once per project, instead of including them per-file.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Allow importing helper functions from tslib once per project, instead of including them per-file.\n\nSee more: https://www.typescriptlang.org/tsconfig#importHelpers"
          },
          "importsNotUsedAsValues":{
            "description":"Specify emit/checking behavior for imports that are only used for types.",
            "default":"remove",
            "enum":[
              "remove",
              "preserve",
              "error"
            ]
          },
          "alwaysStrict":{
            "description":"Ensure 'use strict' is always emitted.",
            "type":"boolean",
            "markdownDescription":"Ensure 'use strict' is always emitted.\n\nSee more: https://www.typescriptlang.org/tsconfig#alwaysStrict"
          },
          "strict":{
            "description":"Enable all strict type checking options.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Enable all strict type checking options.\n\nSee more: https://www.typescriptlang.org/tsconfig#strict"
          },
          "strictBindCallApply":{
            "description":"Check that the arguments for `bind`, `call`, and `apply` methods match the original function.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Check that the arguments for `bind`, `call`, and `apply` methods match the original function.\n\nSee more: https://www.typescriptlang.org/tsconfig#strictBindCallApply"
          },
          "downlevelIteration":{
            "description":"Emit more compliant, but verbose and less performant JavaScript for iteration.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Emit more compliant, but verbose and less performant JavaScript for iteration.\n\nSee more: https://www.typescriptlang.org/tsconfig#downlevelIteration"
          },
          "checkJs":{
            "description":"Enable error reporting in type-checked JavaScript files.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Enable error reporting in type-checked JavaScript files.\n\nSee more: https://www.typescriptlang.org/tsconfig#checkJs"
          },
          "strictFunctionTypes":{
            "description":"When assigning functions, check to ensure parameters and the return values are subtype-compatible.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"When assigning functions, check to ensure parameters and the return values are subtype-compatible.\n\nSee more: https://www.typescriptlang.org/tsconfig#strictFunctionTypes"
          },
          "strictPropertyInitialization":{
            "description":"Check for class properties that are declared but not set in the constructor.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Check for class properties that are declared but not set in the constructor.\n\nSee more: https://www.typescriptlang.org/tsconfig#strictPropertyInitialization"
          },
          "esModuleInterop":{
            "description":"Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility.\n\nSee more: https://www.typescriptlang.org/tsconfig#esModuleInterop"
          },
          "allowUmdGlobalAccess":{
            "description":"Allow accessing UMD globals from modules.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Allow accessing UMD globals from modules.\n\nSee more: https://www.typescriptlang.org/tsconfig#allowUmdGlobalAccess"
          },
          "keyofStringsOnly":{
            "description":"Make keyof only return strings instead of string, numbers or symbols. Legacy option.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Make keyof only return strings instead of string, numbers or symbols. Legacy option.\n\nSee more: https://www.typescriptlang.org/tsconfig#keyofStringsOnly"
          },
          "useDefineForClassFields":{
            "description":"Emit ECMAScript-standard-compliant class fields.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Emit ECMAScript-standard-compliant class fields.\n\nSee more: https://www.typescriptlang.org/tsconfig#useDefineForClassFields"
          },
          "declarationMap":{
            "description":"Create sourcemaps for d.ts files.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Create sourcemaps for d.ts files.\n\nSee more: https://www.typescriptlang.org/tsconfig#declarationMap"
          },
          "resolveJsonModule":{
            "description":"Enable importing .json files",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Enable importing .json files\n\nSee more: https://www.typescriptlang.org/tsconfig#resolveJsonModule"
          },
          "assumeChangesOnlyAffectDirectDependencies":{
            "description":"Have recompiles in projects that use `incremental` and `watch` mode assume that changes within a file will only affect files directly depending on it.",
            "type":"boolean",
            "markdownDescription":"Have recompiles in projects that use `incremental` and `watch` mode assume that changes within a file will only affect files directly depending on it.\n\nSee more: https://www.typescriptlang.org/tsconfig#assumeChangesOnlyAffectDirectDependencies"
          },
          "extendedDiagnostics":{
            "description":"Output more detailed compiler performance information after building.",
            "type":"boolean",
            "default":false,
            "markdownDescription":"Output more detailed compiler performance information after building.\n\nSee more: https://www.typescriptlang.org/tsconfig#extendedDiagnostics"
          },
          "listFilesOnly":{
            "description":"Print names of files that are part of the compilation and then stop processing.",
            "type":"boolean"
          },
          "disableSourceOfProjectReferenceRedirect":{
            "description":"Disable preferring source files instead of declaration files when referencing composite projects",
            "type":"boolean",
            "markdownDescription":"Disable preferring source files instead of declaration files when referencing composite projects\n\nSee more: https://www.typescriptlang.org/tsconfig#disableSourceOfProjectReferenceRedirect"
          },
          "disableSolutionSearching":{
            "description":"Opt a project out of multi-project reference checking when editing.",
            "type":"boolean",
            "markdownDescription":"Opt a project out of multi-project reference checking when editing.\n\nSee more: https://www.typescriptlang.org/tsconfig#disableSolutionSearching"
          }
        }
      }
    }
  },
  ...,
}

compileOptions : type

{
  ...,
  "typeRoots": {
    "description": "Specify multiple folders that act like `./node_modules/@types`.",
    "type": "array",
    "uniqueItems": true,
    "items": {
      "type": "string"
    },
    "markdownDescription": "Specify multiple folders that act like `./node_modules/@types`.\n\nSee more: https://www.typescriptlang.org/tsconfig#typeRoots"
  },
  "types": {
    "description": "Specify type package names to be included without being referenced in a source file.",
    "type": "array",
    "uniqueItems": true,
    "items": {
      "type": "string"
    },
    "markdownDescription": "Specify type package names to be included without being referenced in a source file.\n\nSee more: https://www.typescriptlang.org/tsconfig#types"
  },
  ...,
}

@types

  • TypeScript 2.0 부터 사용 가능해진 내장 type definition 시스템

  • 아무 설정을 안하면 ?

    • node_modules/@types 라는 모든 경로를 찾아서 사용

  • typeRoots 를 사용하면 ?

    • 배열 안에 들어있는 경로들 아래서만 가져옵니다.

  • types 를 사용하면 ?

    • 배열 안의 모듈 혹은 ./node_modules/@types/ 안의 모듈 이름에서 찾아옵니다.

    • [] 빈 배열을 넣는다는건 이 시스템을 이용하지 않겠다는 것입니다.

  • typeRoots 와 types 를 같이 사용하지 않습니다.

compileOptions

- target 과 lib

compileOptions : target

{
  "target": {
    "description": "Set the JavaScript language version for emitted JavaScript and include compatible library declarations.",
    "type": "string",
    "default": "ES3",
    "anyOf": [
      {
        "enum": [
          "ES3",
          "ES5",
          "ES6",
          "ES2015",
          "ES2016",
          "ES2017",
          "ES2018",
          "ES2019",
          "ES2020",
          "ESNext"
        ]
      },
      {
        "pattern": "^([Ee][Ss]([356]|(20(1[56789]|20))|[Nn][Ee][Xx][Tt]))$"
      }
    ],
    "markdownDescription": "Set the JavaScript language version for emitted JavaScript and include compatible library declarations.\n\nSee more: https://www.typescriptlang.org/tsconfig#target"
  },
}

compileOptions : lib

{
  "lib": {
    "description": "Specify a set of bundled library declaration files that describe the target runtime environment.",
    "type": "array",
    "uniqueItems": true,
    "items": {
      "type": "string",
      "anyOf": [
        {
          "enum": [
            "ES5", "ES6", "ES2015", "ES2015.Collection", "ES2015.Core", "ES2015.Generator", "ES2015.Iterable", "ES2015.Promise", "ES2015.Proxy", "ES2015.Reflect", "ES2015.Symbol.WellKnown", "ES2015.Symbol", "ES2016", "ES2016.Array.Include", "ES2017", "ES2017.Intl", "ES2017.Object", "ES2017.SharedMemory", "ES2017.String", "ES2017.TypedArrays", "ES2018", "ES2018.AsyncGenerator", "ES2018.AsyncIterable", "ES2018.Intl", "ES2018.Promise", "ES2018.Regexp", "ES2019", "ES2019.Array", "ES2019.Object", "ES2019.String", "ES2019.Symbol", "ES2020", "ES2020.BigInt", "ES2020.Promise", "ES2020.String", "ES2020.Symbol.WellKnown", "ESNext", "ESNext.Array", "ESNext.AsyncIterable", "ESNext.BigInt", "ESNext.Intl", "ESNext.Promise", "ESNext.String", "ESNext.Symbol", "DOM", "DOM.Iterable", "ScriptHost", "WebWorker", "WebWorker.ImportScripts"
          ]
        },
        {
          "pattern": "^[Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]7$"
        },
        {
          "pattern": "^[Ee][Ss]2015(\\.([Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Rr][Ee]|[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Pp][Rr][Oo][Xx][Yy]|[Rr][Ee][Ff][Ll][Ee][Cc][Tt]|[Ss][Yy][Mm][Bb][Oo][Ll].[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"
        },
        {
          "pattern": "^[Ee][Ss]2016(\\.[Aa][Rr][Rr][Aa][Yy].[Ii][Nn][Cc][Ll][Uu][Dd][Ee])?$"
        },
        {
          "pattern": "^[Ee][Ss]2017(\\.([Ii][Nn][Tt][Ll]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]))?$"
        },
        {
          "pattern": "^[Ee][Ss]2018(\\.([Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ii][Nn][Tt][Ll]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Rr][Ee][Gg][Ee][Xx][Pp]))?$"
        },
        {
          "pattern": "^[Ee][Ss]2019(\\.([Aa][Rr][Rr][Aa][Yy]|[Oo][Bb][Jj][Ee][Cc][Tt]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"
        },
        {
          "pattern": "^[Ee][Ss]2020(\\.([Bb][Ii][Gg][Ii][Nn][Tt]|[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ss][Tt][Rr][Ii][Nn][Gg]|[Ss][Yy][Mm][Bb][Oo][Ll].[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]))?$"
        },
        {
          "pattern": "^[Ee][Ss][Nn][Ee][Xx][Tt](\\.([Aa][Rr][Rr][Aa][Yy]|[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Bb][Ii][Gg][Ii][Nn][Tt]|[Ii][Nn][Tt][Ll]|[Ss][Yy][Mm][Bb][Oo][Ll]))?$"
        },
        {
          "pattern": "^[Dd][Oo][Mm](\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee])?$"
        },
        {
          "pattern": "^[Ss][Cc][Rr][Ii][Pp][Tt][Hh][Oo][Ss][Tt]$"
        },
        {
          "pattern": "^[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr](\\.[Ii][Mm][Pp][Oo][Rr][Tt][Ss][Cc][Rr][Ii][Pp][Tt][Ss])?$"
        }
      ]
    },
    "markdownDescription": "Specify a set of bundled library declaration files that describe the target runtime environment.\n\nSee more: https://www.typescriptlang.org/tsconfig#lib"
  }
}

target 과 lib

  • target

    • 빌드의 결과물을 어떤 버전으로 할 것이냐

    • 지정을 안하면 es3 입니다.

  • lib

    • 기본 type definition 라이브러리를 어떤 것을 사용할 것이냐

    • lib 를 지정하지 않을 때,

      • target 이 'es3' 이고, 디폴트로 lib.d.ts 를 사용합니다.

      • target 이 'es5' 이면, 디폴트로 dom, es5, scripthost 를 사용합니다.

      • target 이 'es6' 이면, 디폴트로 dom, es6, dom.iterable, scripthost 를 사용합니다.

    • ​lib 를 지정하면 그 lib 배열로만 라이브러리를 사용하니다.

      • ​빈 [] => 'no definition found 어쩌구'

compileOptions

- outDir, outFile, rootDir

compileOptions : outDir, outFile, rootDir

{
  "outFile": {
    "description": "Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output.",
    "type": "string",
    "markdownDescription": "Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output.\n\nSee more: https://www.typescriptlang.org/tsconfig#outFile"
  },
  "outDir": {
    "description": "Specify an output folder for all emitted files.",
    "type": "string",
    "markdownDescription": "Specify an output folder for all emitted files.\n\nSee more: https://www.typescriptlang.org/tsconfig#outDir"
  },
  "rootDir": {
    "description": "Specify the root folder within your source files.",
    "type": "string",
    "markdownDescription": "Specify the root folder within your source files.\n\nSee more: https://www.typescriptlang.org/tsconfig#rootDir"
  }
}

compileOptions

- strict

compileOptions : strict

{
  "strict": {
    "description": "Enable all strict type checking options.",
    "type": "boolean",
    "default": false,
    "markdownDescription": "Enable all strict type checking options.\n\nSee more: https://www.typescriptlang.org/tsconfig#strict"
  }
}

Enable all strict type checking options.

  • --noImplicitAny

  • --noImplicitThis

  • --strictNullChecks

  • --strictFunctionTypes

  • --strictPropertyInitialization

  • --strictBindCallApply

  • --alwaysStrict

5. Interfaces

5-1) What are Interfaces ??    5-2) optional property (1)

5-3) optional property (2)    5-4) function in interface

5-5) class implements interface    5-6) interface extends interface

5-7) function interface    5-8) Readonly Interface Properties

5-9) type alias vs interface

What are Interfaces ??

function hello(person: { name: string; age: number; }): void {
    console.log(`안녕하세요! ${person.name} 입니다.`);
}

const p: { name: string; age: number; } = {
    name: 'Mark',
    age: 35
};

hello(p); // 안녕하세요! Mark 입니다.

///////////////////////////////////////////////////////////////

interface Person {
    name: string;
    age: number;
}

function hello(person: Person): void {
    console.log(`안녕하세요! ${person.name} 입니다.`);
}

const p: Person = {
    name: 'Mark',
    age: 35
};

hello(p); // 안녕하세요! Mark 입니다.

optional property (1)

interface - optional property (1)

interface Person {
    name: string;
    age?: number;
}

function hello(person: Person): void {
    console.log(`안녕하세요! ${person.name} 입니다.`);
}

const p1: Person = {
    name: 'Mark',
    age: 35
};

const p2: Person = {
    name: 'Anna'
};

hello(p1); // 안녕하세요! Mark 입니다.
hello(p2); // 안녕하세요! Anna 입니다.

optional property (2)

interface - optional property (2)

interface Person {
    name: string;
    age?: number;
    [props: string]: any;
}

function hello(person: Person): void {
    console.log(`안녕하세요! ${person.name} 입니다.`);
}

const p1: Person = {
    name: 'Mark',
    age: 35,
};

const p2: Person = {
    name: 'Anna',
    systers: [
        'Sung',
        'Chan'
    ]
};

const p3: Person = {
    name: 'Bokdaengi',
    father: p1,
    mother: p2
};

hello(p1); // 안녕하세요! Mark 입니다.
hello(p2); // 안녕하세요! Anna 입니다.
hello(p3); // 안녕하세요! Bokdaengi 입니다.

function in interface

interface - function in interface

interface Person {
    name: string;
    age: number;
    hello(): void;
}

const p1: Person = {
    name: 'Mark',
    age: 35,
    hello: function (): void {
        console.log(this);
        console.log(`안녕하세요! ${this.name} 입니다.`);
    }
};

const p2: Person = {
    name: 'Mark',
    age: 35,
    hello(): void {
        console.log(this);
        console.log(`안녕하세요! ${this.name} 입니다.`);
    }
};

const p3: Person = {
    name: 'Mark',
    age: 35,
    hello: (): void => {
        console.log(this);
        console.log(`안녕하세요! ${this.name} 입니다.`);
    }
};

p1.hello(); // 안녕하세요! Mark 입니다.
p2.hello(); // 안녕하세요! Mark 입니다.
p3.hello(); // 안녕하세요! 입니다.

class implements interface

class implements interface

interface IPerson {
    name: string;
    age?: number;
    hello(): void;
}

class Person implements IPerson {
    name: string;

    constructor(name: string) {
        this.name = name;
    }

    hello(): void {
        console.log(`안녕하세요! ${this.name} 입니다.`);
    }
}

const person = new Person('Mark');
person.hello(); // 안녕하세요! Mark 입니다.

interface extends interface

interface extends interface

interface Person {
    name: string;
    age?: number;
}

interface Korean extends Person {
    city: string;
}

const k: Korean = {
    name: '이웅재',
    city: '서울'
};

function interface

function interface

interface HelloPerson {
    // (name: string, age: number): void;
    (name: string, age?: number): void;
}

let helloPerson: HelloPerson = function (name: string) {
    console.log(`안녕하세요! ${name} 입니다.`);
};

helloPerson('Mark'); // 안녕하세요! Mark 입니다.

/*

함수의 타입 체크는 할당할때가 아니라 사용할때 한다는 점을 명심

*/

Readonly Interface Properties

type alias vs interface

function

// type alias
type EatType = (food: string) => void;

// interface
interface IEat {
  (food: string): void;
}

array

// type alias
type PersonList = string[];

// interface
interface IPersonList {
  [index: number]: string;
}

intersection

interface ErrorHandling {
  success: boolean;
  error?: { message: string };
}

interface ArtistsData {
  artists: { name: string }[];
}

// type alias
type ArtistsResponseType = ArtistsData & ErrorHandling;

// interface
interface IArtistsResponse extends ArtistsData, ErrorHandling {}

let art: ArtistsResponseType;
let iar: IArtistsResponse;

union types

interface Bird {
  fly(): void;
  layEggs(): void;
}

interface Fish {
  swim(): void;
  layEggs(): void;
}

type PetType = Bird | Fish;

interface IPet extends PetType {} // error TS2312: An interface can only extend an object type or intersection of object types with statically known members.

class Pet implements PetType {} // error TS2422: A class can only implement an object type or intersection of object types with statically known members.

Declaration Merging - interface

interface MergingInterface {
  a: string;
}

interface MergingInterface {
  b: string;
}

let mi: MergingInterface;
mi.

Declaration Merging - type alias

type MergingType = {
  a: string;
};

type MergingType = {
  b: string;
};

6. Classes

6-1) What are Classes ??    6-2) Quick Start - Class

6-3) constructor & initialize    6-4) 접근 제어자 (Access Modifiers)

6-5) initialization in constructor parameters    6-6) Getters & Setters

6-7) readonly properties    6-8) Index Signatures

6-9) Static Properties & Methods    6-10) Singletons

6-11) 상속 (Inheritance)    6-12) Abstract Classes

What are Classes ??

  • object 를 만드는 blueprint (청사진, 설계도)

  • 클래스 이전에 object 를 만드는 기본적인 방법은 function

  • JavaScript 에도 class 는 es6 부터 사용 가능

  • OOP 을 위한 초석

  • TypeScript 에서는 클래스도 사용자가 만드는 타입의 하나

Quick Start - Class

class Person {}

const p1 = new Person();

console.log(p1);
class Person {
  name: string;

  constructor(name: string) {
    this.name = string;
  }
}

const p1 = new Person('Mark');

console.log(p1);
  • class 키워드를 이용하여 클래스를 만들 수 있다.

  • class 이름은 보통 대문자를 이용한다.

  • new 를 이용하여 class 를 통해 object 를 만들 수 있다.

  • constructor 를 이용하여 object 를 생성하면서 값을 전달할 수 있다.

  • this 를 이용해서 만들어진 object 를 가리킬 수 있다.

  • JS 로 컴파일되면 es5 의 경우 function 으로 변경된다.

constructor & initialize

// strictPropertyInitialization : false
class Person {
  name: string;
  age: number;
}

const p1: Person = new Person();
console.log(p1); // Person1 {}
person.age = 39;
console.log(person.name); // undefined
  • 생성자 함수가 없으면, 디폴트 생성자가 불린다.

  • 프로그래머가 만든 생성자가 하나라도 있으면, 디폴트 생성자는 사라진다.

  • strict 모드에서는 프로퍼티를 선언하는 곳 또는 생성자에서 값을 할당해야 한다.

  • 프로퍼티를 선언하는 곳 또는 생성자에서 값을 할당하지 않는 경우에는 ! 를 붙여서 위험을 표현한다.

  • 클래스의 프로퍼티가 정의되어 있지만, 값을 대입하지 않으면 undefined 이다.

  • 생성자에는 async 를 설정할 수 없다.

접근 제어자

(Access Modifiers)

  • 접근 제어자에는 public, private, protected 가 있다.

  • 설정하지 않으면 public 이다.

  • 클래스 내부의 모든 곳에 (생성자, 프로퍼티, 메서드) 설정 가능하다.

  • private 으로 설정하면 클래스 외부에서 접근할 수 없다.

  • 자바스크립트에서 private 지원하지 않아 오랜동안 프로퍼티나 메서드 이름 앞에 _ 를 붙여서 표현했다.

initialization

in constructor parameters

Getters & Setters

readonly properties

Index Signatures in class

Static Properties & Methods

Singletons

상속

(Inheritance)

Abstract Classes

7. Generics

7-1) Generics, Any 와 다른 점    7-2) Generics Basic

7-3) Generics Array & Tuple    7-4) Generics Function

7-5) Generics Class    7-6) Generics with extends

7-7) keyof & type lookup system

Generics, Any 와 다른 점

Generic - Any 와 다른 점

  • hello 의 리턴이 any 이기 때문에 타입 헬퍼가 제대로 되지 않음

  • helloGeneric 을 사용하면 정상적으로 사용가능

function helloString(message: string): string {
  return message;
}

function helloNumber(message: number): number {
  return message;
}

// 더 많은 반복된 함수들 ...

function hello(message: any): any {
  return message;
}

function helloGeneric<T>(message: T): T {
  return message;
}

console.log(hello('Mark').length);
console.log(hello(38).length); // undefined

console.log(helloGeneric('Mark').length);
// console.log(helloGeneric<number>('Mark').length); (X)
console.log(helloGeneric(38).toString());
// console.log(helloGeneric(36).length); (X)

Generics Basic

Generic Basic

  • Generic 타입을 쓰지 않으면, T 를 추론

  • Generic 타입을 쓰면, T 를 검증

function helloBasic<T>(message: T): T {
  return message;
}

console.log(helloBasic<string>('Mark'));
const age = helloBasic(38);
// helloBasic<number>('38'); (X)

Generics Array & Tuple

Generic Array & Tuple

function helloArray<T>(messages: T[]): T {
  return messages[0];
}

function helloTuple<T, K>(messages: [T, K]): T {
  return messages[0];
}

console.log(helloArray(['Hello', 'World'])); // string[]
console.log(helloArray(['Hello', 1])); // Array<string | number>
console.log(helloTuple(['Hello', 'World'])); // [string, string]
console.log(helloTuple(['Hello', 1])); // [string, number]
// console.log(helloTuple(['Hello', 'world', 1])); // Error

Generics Function

Generic Function

type HelloFunctionGeneric = <T>(message: T) => T;

const helloFunction: HelloFunctionGeneric = <T>(message: T): T => {
  return message;
};

console.log(helloFunction<string>('Hello').length);

Generics Class

Generic Class

class Person<T> {
  private _name: T;

  constructor(name: T) {
    this._name = name;
  }
}

new Person('Mark');
// new Person<string>(38); (X)

Generic with multiple types

class Person7<T, K> {
  private _name: T;
  private _age: K;

  constructor(name: T, age: K) {
    this._name = name;
    this._age = age;
  }
}

new Person7('Mark', 38);

Generics with extends

Generic with extends

class Person6<T extends string | number> {
  private _name: T;

  constructor(name: T) {
    this._name = name;
  }
}

new Person6('Mark');
new Person6(38);
// new Person6(true); // T 가 string 또는 number 를 상속받기 때문에 boolean 은 X

keyof & type lookup system

keyof & type lookup system

interface Person8 {
  name: string;
  age: number;
}

const person8: Person8 = {
  name: 'Mark',
  age: 36
};

function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]): void {
  obj[key] = value;
}

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

setProperty(person8, 'name', 'Anna');
// setProperty(person8, 'name', 27);
console.log(getProperty(person8, 'name'));
// console.log(getProperty(person8, 'fullname'));

Type Guard

1. typeof Type Guard - 보통 Primitive 타입일 경우

function getNumber(value: number | string): number {
  value; // number | string
  if (typeof value === 'number') {
    value; // number
	return value;
  }
  value; // string
  return -1;
}

2. instanceof Type Guard

interface IMachine {
  name: string;
}

class Car implements IMachine {
  name: string;
  wheel: number;
}

class Boat implements IMachine {
  name: string;
  motor: number;
}

function getWhellOrMotor(machine: Car | Boat): number {
  if (machine instanceof Car) {
    return machine.wheel; // Car
  } else {
    return machine.motor; // Boat
  }
}

2. instanceof Type Guard - Error 객체 구분에 많이 쓰인다.

class NegativeNumberError extends Error {}

function getNumber(value: number): number | NegativeNumberError {
  if (value < 0) return new NegativeNumberError();

  return value;
}

function main() {
  const num = getNumber(-10);

  if (num instanceof NegativeNumberError) {
    return;
  }

  num; // number
}

3. in operator Type Guard - object 의 프로퍼티 유무로 처리하는 경우

interface Admin {
  id: string;
  role: string:
}

interface User {
  id: string;
  email: string;
}

function redirect(user: Admin | User) {
  if(/*user is admin*/) {
    routeToAdminPage(usr.role);
  } else {
    routeToHomePage(usr.email);
  }
}

3. in operator Type Guard - object 의 프로퍼티 유무로 처리하는 경우

interface Admin {
  id: string;
  role: string:
}

interface User {
  id: string;
  email: string;
}

function redirect(user: Admin | User) {
  if("role" in user) {
    routeToAdminPage(user.role);
  } else {
    routeToHomePage(user.email);
  }
}

4. literal Type Guard - object 의 프로퍼티가 같고, 타입이 다른 경우

interface IMachine {
  type: string;
}

class Car implements IMachine {
  type: 'CAR';
  wheel: number;
}

class Boat implements IMachine {
  type: 'BOAT';
  motor: number;
}

function getWhellOrMotor(machine: Car | Boat): number {
  if (machine.type === 'CAR') {
    return machine.wheel;
  } else {
    return machine.motor;
  }
}

5. custom Type Guard

function getWhellOrMotor(machine: any): number {
  if (isCar(machine)) {
    return machine.wheel;
  } else if (isBoat(machine)) {
    return machine.motor;
  } else {
    return -1;
  }
}

function isCar(arg: any): arg is Car {
    return arg.type === 'CAR';
}

function isBoat(arg: any): arg is Boat {
    return arg.type === 'BOAT';
}

Conditional Types

Item<T> - T 에 따라 달라지는 container

interface StringContainer {
  value: string;
  format(): string;
  split(): string[];
}

interface NumberContainer {
  value: number;
  nearestPrime: number;
  round(): number;
}

type Item1<T> = {
  id: T,
  container: any;
};

const item1: Item1<string> = {
  id: "aaaaaa",
  container: null
};

T 가 string 이면 StringContainer, 아니면 NumberContainer

type Item2<T> = {
  id: T;
  container: T extends string ? StringContainer : NumberContainer;
};

const item2: Item2<string> = {
  id: 'aaaaaa',
  container: null, // Type 'null' is not assignable to type 'StringContainer'.
};

T 가 string 이면 StringContainer T 가 number 면 NumberContainer 아니면 사용 불가

type Item3<T> = {
  id: T extends string | number ? T : never;
  container: T extends string
    ? StringContainer
    : T extends number
    ? NumberContainer
    : never;
};

const item3: Item3<boolean> = {
  id: true, // Type 'boolean' is not assignable to type 'never'.
  container: null, // Type 'null' is not assignable to type 'never'.
};

ArrayFilter<T>

type ArrayFilter<T> = T extends any[] ? T : never;

type StringsOrNumbers = ArrayFilter<string | number | string[] | number[]>;

// 1. string | number | string[] | number[]
// 2. never | never | string[] | number[]
// 3. string[] | number[]

Table or Dino

interface Table {
  id: string;
  chairs: string[];
}

interface Dino {
  id: number;
  legs: number;
}

interface World {
  getItem<T extends string | number>(id: T): T extends string ? Table : Dino;
}

let world: World = null as any;

const dino = world.getItem(10);
const what = world.getItem(true); // Error! Argument of type 'boolean' is not assignable to parameter of type 'string | number'.ts(2345)

Flatten<T>

type Flatten<T> = T extends any[]
  ? T[number]
  : T extends object
  ? T[keyof T]
  : T;


const numbers = [1, 2, 3];
type NumbersArrayFlattened = Flatten<typeof numbers>;
// 1. number[]
// 2. number

const person = {
  name: 'Mark',
  age: 38
};
                             
type SomeObjectFlattened = Flatten<typeof person>;
// 1. keyof T --> "id" | "name"
// 2. T["id" | "name"] --> T["id"] | T["name"] --> number | string

const isMale = true;
type SomeBooleanFlattened = Flatten<typeof isMale>;
// true

infer

type UnpackPromise<T> = T extends Promise<infer K>[] ? K : any;
const promises = [Promise.resolve('Mark'), Promise.resolve(38)];

type Expected = UnpackPromise<typeof promises>; // string | number

함수의 리턴 타입 알아내기 - MyReturnType

function plus1(seed: number): number {
  return seed + 1;
}

type MyReturnType<T extends (...args: any) => any> = T extends (
  ...args: any
) => infer R
  ? R
  : any;

type Id = MyReturnType<typeof plus1>;

lookupEntity(plus1(10));

function lookupEntity(id: Id) {
  // query DB for entity by ID
}

내장 conditional types (1)

// type Exclude<T, U> = T extends U ? never : T;
type Excluded = Exclude<string | number, string>; // number - diff

// type Extract<T, U> = T extends U ? T : never;
type Extracted = Extract<string | number, string>; // string - filter

// Pick<T, Exclude<keyof T, K>>; (Mapped Type)
type Picked = Pick<{name: string, age: number}, 'name'>;

// type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
type Omited = Omit<{name: string, age: number}, 'name'>;

// type NonNullable<T> = T extends null | undefined ? never : T;
type NonNullabled = NonNullable<string | number | null | undefined>;

내장 conditional types (2)

/*
type ReturnType<T extends (...args: any) => any> = T extends (
  ...args: any
) => infer R
  ? R
  : any;
*/

/*
type Parameters<T extends (...args: any) => any> = T extends (
  ...args: infer P
) => any
  ? P
  : never;
*/
type MyParameters = Parameters<(name: string, age: number) => void>; // [name: string, age: number]

내장 conditional types (3)

interface Constructor {
  new (name: string, age: number): string;
}

/*
type ConstructorParameters<
  T extends new (...args: any) => any
> = T extends new (...args: infer P) => any ? P : never;
*/

type MyConstructorParameters = ConstructorParameters<Constructor>; // [name: string, age: number]

/*
type InstanceType<T extends new (...args: any) => any> = T extends new (
  ...args: any
) => infer R
  ? R
  : any;
*/

type MyInstanceType = InstanceType<Constructor>; // string

Function 인 프로퍼티 찾기

type FunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? K : never;
}[keyof T];
type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>;

type NonFunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? never : K;
}[keyof T];
type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>;

interface Person {
  id: number;
  name: string;
  hello(message: string): void;
}

type T1 = FunctionPropertyNames<Person>;
type T2 = NonFunctionPropertyNames<Person>;
type T3 = FunctionProperties<Person>;
type T4 = NonFunctionProperties<Person>;

Method Overloads

오버로딩이 불가능한 자바스크립트에 타입을 붙이는 경우

function shuffle(value: string | any[]): string | any[] {
  if (typeof value === 'string')
    return value
      .split('')
      .sort(() => Math.random() - 0.5)
      .join('');
  return value.sort(() => Math.random() - 0.5);
}

console.log(shuffle('Hello, Mark!')); // string | any[]
console.log(shuffle(['Hello', 'Mark', 'long', 'time', 'no', 'see'])); // string | any[]
console.log(shuffle([1, 2, 3, 4, 5])); // string | any[]

제네릭을 떠올리자! => conditional type 활용

function shuffle2<T extends string | any[]>(
  value: T,
): T extends string ? string : T;
function shuffle2(value: any) {
  if (typeof value === 'string')
    return value
      .split('')
      .sort(() => Math.random() - 0.5)
      .join('');
  return value.sort(() => Math.random() - 0.5);
}

// function shuffle2<"Hello, Mark!">(value: "Hello, Mark!"): string
shuffle2('Hello, Mark!');

// function shuffle2<string[]>(value: string[]): string[]
shuffle2(['Hello', 'Mark', 'long', 'time', 'no', 'see']);

// function shuffle2<number[]>(value: number[]): number[]
shuffle2([1, 2, 3, 4, 5]);

// error! Argument of type 'number' is not assignable to parameter of type 'string | any[]'.
shuffle2(1);

오버로딩을 활용하면?

function shuffle3(value: string): string;
function shuffle3<T>(value: T[]): T[];
function shuffle3(value: string | any[]): string | any[] {
  if (typeof value === 'string')
    return value
      .split('')
      .sort(() => Math.random() - 0.5)
      .join('');
  return value.sort(() => Math.random() - 0.5);
}

shuffle3('Hello, Mark!');
shuffle3(['Hello', 'Mark', 'long', 'time', 'no', 'see']);
shuffle3([1, 2, 3, 4, 5]);

클래스의 메서드 오버로딩 : 작성자

class ExportLibraryModal {
  public openComponentsToLibrary(
    libraryId: string,
    componentIds: string[],
  ): void;
  public openComponentsToLibrary(componentIds: string[]): void;
  public openComponentsToLibrary(
    libraryIdOrComponentIds: string | string[],
    componentIds?: string[],
  ): void {
    if (typeof libraryIdOrComponentIds === 'string') {
      if (componentIds !== undefined) { // 이건 좀 별루지만,
        // 첫번째 시그니처
        libraryIdOrComponentIds;
        componentIds;
      }
    }

    if (componentIds === undefined) { // 이건 좀 별루지만,
      // 두번째 시그니처
      libraryIdOrComponentIds;
    }
  }
}

클래스의 메서드 오버로딩 : 사용자

const modal = new ExportLibraryModal();

modal.openComponentsToLibrary(
  'library-id',
  ['component-id-1', 'component-id-1'],
);

modal.openComponentsToLibrary(['component-id-1', 'component-id-1']);

TypeScript Basic - Part 1

By Woongjae Lee

TypeScript Basic - Part 1

타입스크립트 기초 강의 파트1

  • 229