ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TypeScript] Declare 의 용도
    Computer Science/TypeScript 2023. 11. 19. 23:03

    TypeScript에서 Declare 키워드는 주로 외부 라이브러리나 모듈을 정의할 때 사용된다.

    Declare의 용도는 함수, 클래스 등이 어딘가에 이미 선언이 되었다고 TypeScript 컴파일러에 알리는 용도이다. 즉 TypeScript로 작성되지 않은 코드에서 타입 정보를 주고 싶을 때 사용된다.

    따라서 JS 로 변환될때 전부 사라진다. 이러한 이유로 Type 같은 경우에 어차피 JS 코드로 변환되지 않으므로 declare 키워드를 사용하지 않아도 된다.

    //index.ts
    type testType = {
        name: string;
        age: number;
    }
    
    const test: testType = {
        name: 'test',
        age: 10
    }
    
    /////////////////////////
    //index.ts
    declare type testType = {
        name: string;
        age: number;
    }
    
    const test: testType = {
        name: 'test',
        age: 10
    }

    둘다 동일하게 아래와 같이 결과가 나온다.

    //index.js
    var test = {
        name: 'test',
        age: 10
    };
    console.log(test.name);

     

    Type의 정보만 나타내주고 JS로 변환되지 않는 특성으로 주로 .d.ts 파일에 정보들을 저장해놓는다.

     

    declare로 사용되는 것은 크게 3가지가 존재하는데 namespace, module, global이다.

    우선 declare 로 선언된 영역 안에서는 declare를 붙이지 않아도 기본으로 declare가 붙는다.

    추가로 declare 내부에는 타입 선언 관련된 코드만 작성이 가능하다. 이는 당연한 것이 해당 코드는 js로 변환되지 않기에 로직은 들어가서는 안된다.

     

    declare namespace, declare module

    namespace는 주로 내가 작성한 코드의 타입을 정의할 때 사용하며 module은 외부 라이브러리를 가져와 사용할 때 type을 추가하고 싶다면 사용된다.

    예를 들어 namespace의 경우 React에서 useStae 등의 타입을 정의할 때 사용된다.

    //타입스트립트 교과서 330p
    declare namepsace React {
    	...
        function useState<S>(initialState: S| (() => S)): [S, Dispatch<SetStateAction<S>>];
        function useState<S = undefined>(): [S | undefined, Dispatch<SetStateAction<S | undefined>>};
        ...
    }
    ...

     

    module의 경우 다음과 같다.

    쉽게 test 가능한 것으로 http같은 경우가 있을 텐데 기존 Typescript에서 http를 import한다면 error가 발생한다.

    import http from 'http'; //TS2307: Cannot find module  http  or its corresponding type declarations.
    
    http.createServer((req, res) => {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('Hello World!');
    });

    이는 Node.js는 기본적으로 CommonJS 모듈 시스템을 사용하므로 import fs = require('fs')를 하는게 맞으나 tsconfig.json에서 esModuleInterop 옵션을 활성화한다면 해당 import 문법이 가능해야한다. 허나 그럼에도 에러가 발생하는 이유는 타입스크립트가 이 모듈에 대한 타입 정의를 가지고 있지 않기 때문이다.

    @types/node 패키지에서 해당 타입을 가지고 있는데 안으로 들어가보면 다음과 같이 정의하고 있다.

    //타입스크립트 교과서 380p
    declare module 'http' {
    	...
    }
    declare module 'node:http' {
    	export * from 'http'
    }

    이로서 타입스크립트에게 해당 모듈이 있다는 것을 알리고 사용이 가능해진다.

     

    declare global

    전역 객체의 경우 import 하는 것이 아니기에 별도로 존재한다. 대표적으로 React의 JSX 같은 경우이다.

    //타입스크립트 교과서 350p
    declare global {
    	namespace JSX {
        	interface Element extends React.ReactElement<any,any> {}
            interface ElementClass extends React.Component<any> {
            	render(): React.ReactNode;
            }
            ...
    }

    이로서 import 없이도 JSX.Element 등을 자유롭게 사용할 수 있다.

     

    'Computer Science > TypeScript' 카테고리의 다른 글

    Utility Types ( Partial, Required, Pick&Omit )  (0) 2023.10.21
    Template Literal Type  (0) 2023.10.14
    infer  (1) 2023.09.30
    type vs interface  (0) 2023.09.22
    TSC vs Babel  (0) 2023.09.15
Designed by Tistory.