typescript에서는 ts 파일끼리는 글로벌 모듈 (ambient module)로 import, export를 안해도 자동으로 가져다 쓸 수가 있다고 배웠다.
그러면 자동으로 local module로 지정되는 방법?,문법?이런게 있을까 하다가 d.ts라는 파일을 알게 되었다.
.d.ts
에 있는 type들은 local module이다. 쓰고싶으면 import, export 해야한다.한 ts 파일에 타입들이 많아지면 타입만을 따로 빼고 import해서 사용하고 싶은 욕망과, ambient module이라는 특징 때문에 걱정이 있다면
d.ts 확장명을 사용하여 localmodule로 타입들만 정의해버리자.
.d.ts
에는 타입 정의만 넣을 수 있다 .
type 키워드, interface 를 이용해서
// test.d.ts
type A = number;
type Fn = (x:number) => number
interface Person { naem: string, age :string }
let a : number; // 안됨
let test = 1 // 안된다.
// Q. 변수 타입 지정하고 싶은가?
// A. declare, export keyword
// a라는 변수의 타입을 .d.ts에서 선언 해주고싶으면
declare let a : number // 무쓸모... 라고 생각을 아직까지 함
// 아니면 export 해주자
export let a : number // 무쓸모.. 라고 생각을 아직까지 함
변수 타입 선언을 하면 뭐하나... 재 할당이 안되는데....
index.ts에서
// index.ts
let a: A = 1;// 불가능
// .d.ts에 있는 타입 쓰려면 import 해야함
import { A } from "./index.d";
let a: A = 1; // 가능
레퍼런스용으로 사용하려면 타입들이 좀 이쁘게 정리되어있어야 하지 않을까??
이럴때 tsconfig에 가서
{
"compilerOptions": {
"target": "es5",
"module": "es6",
"declaration": true, // 이걸 true로 해놓으면 됨
}
}
tsconfig에다가 declaration 옵션을 true로 바꿔주면
ts 파일을 저장 시 d.ts 파일이 옆에 생성되고
d.ts파일을 열어보면 타입정의만 쭉 정리되어서 담겨있는것을 볼 수 가있다.
// index.ts
let 이름 :string = 'kim';
let 나이 = 20;
interface Person { name : string }
let 사람 :Person = { name : 'park' }
ts에서 작성하면
// index.d.ts에서
declare let 이름: string;
declare let 나이: number;
interface Person {
name: string;
}
declare let 사람: Person;
이런 파일이 '자동' 생성된다.
레퍼런스 용으로 딱인것 같긴하다.
tsconfig.json에서 옵션 설정을 안했다는 가정하에 export없이 local module을 사용하고 싶을 때도 있지 않을까??
{
"declaration": true, // 이거 없다는 가정하이다.
}
프로젝트 폴더 내에 types/common이런 폴더를 만들고
tsconfing.json 파일에 "typeRoots": ["./types"] 옵션을 추가해주면 ts 파일 작성 할 때 타입이 없다면 자동으로 여기서 타입 찾아서 적용을 해준다.
// tsconfig
{
"compilerOptions": {
..
...
"declaration": false, // 이거 false로 만들고 typeRoots 쓰자
// types라는 폴더에 있는 d.ts 파일'들'을 전역으로 사용가능
"typeRoots": ["./types"]
}
}
이 common.d.ts에서 type들 지정해주면 알아서 적용가능하다.
// types/common/common.d.ts
type A = number
type B = string
// test.ts
const sampleA : A = 1 // 가능
const sampleB : B = 'Choi' // 가능
위의 옵션을 쓸 경우 주의할 점은
"declaration": false
로 하던 지우던하고 하자"typeRoots": ["./types"]
이 옵션 자체가 의미가 없어지기 때문이다.
그런데 저런 옵션은 또 어떨 때 사용할 수 있을까?
jquery나 bootstrap 애니메이션 라이브러리 같은거 가져다 쓸 때 사용할 수 있지 않을까??
내가 직접 jqeury.d.ts 파일을 만들어서 타입정의를 하면 되는데
위와 같이 jquery같은 라이브러리의 d.ts파일을 누군가는 감사하게도 만들었기 때문에 그걸 찾아서 다운받고 전역적으로 쓸 수 있게
{
"compilerOptions": {
..
...
"typeRoots": ["./jquery"]
}
}
이렇게 해놓고 사용하면 되지않을까 싶다.
그래서 라이브러리의 d.ts 파일들이 어디있냐면은
Definitely Typed github repository에서 찾아보자
아니면 npm, yarn 과 같이 라이브러리 설치 할 때 타입스크립트 타입정의된 버전을 따로 찾아서 설치 할 수 있는데 타입이 정의된 라이브러리를 npm,yarn으로 설치하면
node_modules/@types 이런 경로에 타입이 설치된다. 그러면 자동으로 타입지정이 전역적으로 된다.
참고로 'typeRoots' 옵션이 있을 경우 node_modules/@types
폴더를 추가해야 하며, 아니면 typeRoots 옵션을 제거해보자
따로 타입부분만 yarn,npm 으로 설치할 수도 있는데
예를 들어 npm install --save @types/jquery 이렇게 강제 설치하면 jquery 문법 사용할 때 타입정의 안해두 된다.
d.ts를 공부하면서 라이브러리 설치할 때 왜 따로 @types/jquery와 같은 것들을 설명하고 있는지 어느정도 이해하는데 큰 도움이 되었다.
내가 javascript 라이브러리를 사용할 때 d.ts가 있는지 먼저 살펴보고 해야 하는 통찰력을 약간은 얻은것 같다 .