// 실습 (VS code 터미널)
$ npm i react // react 설치
// ts에서 에러발생 => import React from "react";
$ npm i --save-dev @types/react
npm i --save-dev @types/react
: 외부 js
파일들을 자동으로 타입 설정 해주는 패키지 React
는 js
파일이기 때문에 타입 지정을 자동으로 설정해주는 패키지를 설치하야 한다. typeRoots
"typeRoots": ["./node_modules/@types", "./types"],
- 타입은 배열이며 배열안의 타입은
String
입니다.TypeScript2.0
부터 가능해진 내장type definition
시스템으로 인해서@types/....
로 설치한 패키지는types
나typeRoots
를 설정해주지 않아도 기본적으로 자동으로 모두 읽어와서 활용하게 됩니다.- 즉,
node_modules/@types
내의 모든 경로를 찾아서 사용합니다.- 만약, 외부 패키지가 타입을 제공하지 않으면 직접 타입을 만들어야 하는데, 이 경우에 다음과 같이 설정해놓은 후, 기본
definityle typed
와 별도로 만들어준 타입을 동시에 사용하곤 합니다.
{ "compilerOptions": { "typeRoots" : ["./typings"] } }
- 여기서 중요한 점은 기본값인
./node_module/@types
도 명시해야 한다는 점입니다../node_modules/@types
경로를 주지 않으면 이 경로에 있는 패키지들이 설치되었다고 하더라도 사용하지 않습니다.
types
{ "compilerOptions": { "types" : ["node", "lodash", "express"] } }
- 타입은 배열이며 배열안의 타입은
String
입니다.types
를 사용하면 배열 안의 모듈 혹은./node_modules/@type/
안의 모듈 이름에서 찾아옵니다.[]
빈 배열을 넣는다는건 이 시스템을 이용하지 않겠다는 것입니다.typeRoots
와types
를 같이 사용하지 않습니다.
target
: 어떤 런타임에서 실행 할 수 있는 지 결정해줌.type definition
이 되어 있어야 함.lib
: 내가 최종적으로 실행하고자 하는 환경에 맞게 기본 타입들을 결정해서 작업에 문제가 없도록 사전에 예방을 해줌.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", "ES2021", "ESNext" ] }, { "pattern": "^([Ee][Ss]([356]|(20(1[56789]|2[01]))|[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" },
// test.ts const hello = () => { }; // tsconfig.json "target": "es6",
$ npx tsc // ts에서 js로 컴파일
// test.js "use strict"; const hello = () => { };
ES5
,ES6
등 버전을target
에 작성해주어 그에 맞도록JS
파일로 컴파일 해줌- 빌드의 결과물을 어떤 버전으로 할 것이냐에 관한 설정
- 지정을 안하면
ES3
입니다.
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", ... ] }, { "pattern": "^[Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]7$" },
- 기본
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
어쩌구" 에러 발생.
outFile
: 하나의 파일로 합쳐서 컴파일 진행 후 반환rootDir
: 컴파일을 시작하는 루트 폴더(설정 안하면 자동으로 가장 상위 디렉토리 지정)outDir
: 컴파일 후 생성되는 js
파일이 생성될 폴더명"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" },
- 컴파일할 파일들의 컴파일 후에 저장되는 파일들의 경로 설정을 도와줌.
rootDir
을 설정안해주면ts
파일의 상위 폴더를root
로 지정하고 생성함.
4-1.noImplicitAny
옵션
any
라고 판단하게 되면 컴파일 에러를 발생시켜 명시적으로 지정하도록 유도한다.function test(a){ // noImplicitAny로 인한 에러 발생
// ToDo...
}
test(10) // 아예 사용 불가
함수 매개변수 객체 타입 지정
// interface 지정 interface PersonInterface { name: string; } // type alias 지정 type PersonAlias{ name: string; } function test(obj: PersonInterface) { } test({ name: 'user' }) test('aa') // 컴파일 에러
suppressImplicitAnyIndexErrors
noImplicitAny
사용할 때, 인덱스 객체에 인덱스signature
가 없는 경우 오류를 발생 하는데 이를 예외처리한다.var obj = { bar: 10 } obj.baz = 10 // 원래 에러를 발생하나 위 옵션을 사용하면 해결
4-2.noImplicitThis 옵션
any
타입을 사용하지 않고, this
표현식을 사용시 에러 발생function test(name: string) {
this.name = name // 에러 발생
}
해결방안
function test(this: any, name: string) { this.name = name }
- 첫번째 매개변수 자리에
this
를 넣고 타입 지정해준다.typescript
에서만 허용한 문법이다.
Class
에서는this
를 사용하면서noImplicitThis
에러가 발생하지 않는다.- 메소드에 자동으로 클래스 타입이
this
로 지정된다.- 단,
constructor
함수의 첫번째 매개변수로this
사용 불가
4-3.strictNullChecks 옵션
null
과 undefined
제거undefined
에 void
할당 가능)
strictNullChecks
설정 Xfunction test(a: number) { // 리턴 타입 number로 추론 if (a > 0) { return a * 5; } } test(5) + 5 // 30 test(-5) + 5 // NaN (undefined + 5) 컴파일 에러 발생x
strictNullChecks
설정 Ounction test(a: number) { // 리턴 타입 number | undefined 로 추론 if (a > 0) { return a * 5; } } test(5) + 5 // 30 test(-5) + 5 // 컴파일 에러 발생 (undefined + 5)
4-4.strictFunctionTypes 옵션
class Person{}
class Man extends Person{}
class Boy extends Man{}
function test(f: (p: Man) => Man) {}
test((p: Boy): Man =>{}) // 매개변수가 하위타입인 경우 컴파일 에러
- 반공변: 함수의 매개변수 타입만 같거나 슈퍼타입인 경우 할당 가능
- 공변: 같거나 서브 타입인 경우 할당 가능
let sub: string = '' let sup: string | number = sub // 가능
- 함수의 매개변수는 반공변(같거나 상위)이여야하고 반환값은 공변(같거나 하위)이여야 한다.
4-5.strictPropertyInitialization 옵션
strictNullChecks
와 함께 사용class Person{
private _name: string; // 초기화 안해서 에러 발생
}
해결방안 - constructor에서 초기화
class Person{ private _name: string; constructor(name: string){ this._name = name } }
해결방안 - constructor에서 안하는 경우(
!
사용)class Person{ private _name!: string; public async initialize(name: string){ this._name = name } }
4-6.strictBindCallApply 옵션
bind
, call
, apply
에 대해 더 엄격한 검사 수행4-7.alwaysStrict 옵션
JavaScript
의 strict mode
로 코드를 분석하고 strict mode
해제