본문 바로가기
  • 삽질하는 자의 블로그
React/React-TypeScript

1. TypeScript 의 기본 설명과 문법, 그리고 redeclare 오류

by 이게뭐당가 2022. 12. 23.

타입스크립트에 대하여

1. TypeScript 는 JavaScript 의 슈퍼셋(Superset) 이다.

이미 자바스크립트의 기능은 전부 존재하고, 추가적인 기능들을 넣어둔 슈퍼셋이다.

 

2. JavaScript 는 "동적 타입" 언어이다.

    자바스크립트는 동적 타입 언어이다.

           function add (a,b){
                return a + b
            }

            const result = add(2,3)         //  5
            const result2 = add("2","3")    // "23"

    위의 파라미터 a 와 b 의 타입은 string 일 수도, number 일 수도 있다.

    이는 "암묵적 타입 변환" 에 의해, 판단되고, 변하게 된다.

    이게 좋을 수도 있다.

    하지만, 유동성이 있다는 것은 그만큼 "버그" 를 불러온다.

3. TypeScript 의 사용 이유. "정적 타입(Static Type)" 생성 

    "정적 타입"이란, "변수의 타입을 고정시키고 사용 하는 것"이다.
    마치 String(3) 이나 Number(3) 처럼

        function add (a: number ,b: number){
            return a + b
        }

        const result = add(2,3)         // 5
        const result2 = add("2","3")    // "에러 string 사용 불가"
        
	우리는 "정적 타입" 에 의해, 확실한 타입을 가지고, 작업을 할 수 있으며,
    혹시모를 타입 변환에 의해, 결과값이 달리지는 오류를 피할 수 있다.

 

4. 브라우저는 타입스크립트를 이해할 수 없다.

브라우저가 이해하는 언어로 변환 하기 위해, 

우리는 타입스크립트를 자바스크립트로 컴파일 해야한다.

https://www.typescriptlang.org/download

타입스크립트의 기본 프로세스

 

1. 설치

    https://www.typescriptlang.org/download

    npm install typescript --save-dev

 

2. 컴파일 하기

    특정 파일 컴파일

    npx tsc xxx.ts

3. 컴파일 하면, 타입스크립트가 에러를 찾아준다.

 [에러 콘솔]
 
        basic.ts:6:21 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

        6 const result2 = add("2","3")
                        ~~~

 

타입스크립트의 기본 문법

 

1. 원시형 값

        let age: number;
        age = 12;
        age = "12" // error

        let name: string;
        name = "ms";

        let isName: boolean;
        isName = true;

    * 타입은 반드시 소문자여야한다

    * 대문자일 경우

   		let age:Number   // 자바스크립트 객체 Number 를 가르킨다.

 

2. 배열

    ArrayName : <type>[]  으로 지정한다.

        let hobbies: string[];      // "하비" 라는 배열을 만들었따. string 타입의 배열이다.
        hobbies = ["soccer", "baseball"];

        let special: string[] = ["soccer", "baseball"];     // 한번에 정리

3. 객체

    ObjName : {
        propsName : <type>
        propsName : <type>
    }

            let animal: {       // 애니멀이란 객체를 생성했다. 프로퍼티의 타입은 이렇다.
                name: string;   // ; 으로 한줄씩 마무리
                age: number;
            };

            animal = {
                name: "js",
                age: 23,
            };
            
            let animal:{name:string; age:number} = {
                name:"js",
                age:23
            }

 

4. 배열 객체 

    let animals: { name: string; age: number}[]		//  배열이 있는 객체를 생성한다. 객체 안의 타입은 저렇다.

    animals = [
        { name: "cs", age: 5 },
        { name: "bs", age: 25 },
        { name: "ks", age: 35 },
    ];


    let animals: { name: string; age: number }[] = [    // 한번에
        { name: "cs", age: 5 },
        { name: "bs", age: 25 },
        { name: "ks", age: 35 },
    ];

 

5. 여러 타입을 동시에 지정하기

    number 와 string 의 타입이 동시에 존재하는 "멀티 타입의 값을 만들자"

    	let food: string | number = "potato";

    	food = 3;
        
	타입이 string 만 지정되어 있으면 오류가 나겠지만
    
    string | number 로 지정되어 둘 모두 가능하다.

 

6. 타입 별칭(Type aliases) 의 사용 **** 중요!

    type Person = {     // Person 이란 타입은, 저렇게 될 것이다.
        name: string;
        age: number;
    };
    
    const people: Person = {    // 미리 정해놓은 타입을 입력한다.
        name: "js",
        age: 23,
    };
    
    const friends: Person[] = [     // 미리 정해놓은 타입을 입력한다.(배열에 혼합하여)
        { name: "cs", age: 23 },
        { name: "ys", age: 52 },
    ];

Type aliases 는, 타입의 아웃소싱에 필수적인 요소로 사용된다.

 

 

7. 제네릭(Generic) **** 중요!!

    [제네릭을 사용하지 않는다면]
       
       	function insertAtBeginning(array: any[], value: any) {
            return [value, ...array];
        }

        const demoArray = [1, 2, 3];
        const demoStrArray = ["a", "b", "c"];

        const newArray = insertAtBeginning(demoArray, 4);
        const stringArray = insertAtBeginning(demoStrArray, "d");

    ==> 둘 다, "결과값의 타입"이 "any" 이다. ==> "타입스크립트의 도움을 전혀 받을 수 없다."
    	둘 모두의 결과값이, 파라미터의 타입을 따르게 만들 수 있다.(동적 타입)

    [ 제네릭의 사용 ]
    
    	< > 안에, 타입의 파라미터 같은 것을 만드는 것

            function gendricsInsertAtBeginning<T>(array: T[], value: T) {	// 기본 제네릭
                return [value, ...array];
            }

            const gendricsDemoArray = [1, 2, 3];
            const gendricsDemoStrArray = ["a", "b", "c"];

            const newGendricsArray = gendricsInsertAtBeginning(gendricsDemoArray, 4);
            const stringGendricsArray = gendricsInsertAtBeginning(gendricsDemoStrArray,"d");

    ==> 둘 모두의 결과값이, 파라미터의 값을 따라간다.
    	"만약 두개의 파라미터가 서로 타입이 같지 않다면"
    	"제네릭에 의해, 오류가 발생될 것이다."
   		 이는 타입스크립트로 타입검증을 한 것이다.

 

8. 함수의 타입

    function moreAdd(a: number, b: number): number {    // 파라미터, 결과까지 전부 지정
        return a + b;
    }
    
 
    function lessAdd(a: number, b: number) {       // 파라미터만 지정, 결과는 추론으로 나오도록
        return a + b;
    }

 

 

9. 타입 void

      function justPrint() {
            console.log("print");
        }
    
    마우스를 올려보면, [ justPring() : void ] 라는 타입을 볼 수 있다.
    이는 "undefined 와 거의 동일"하다고 보면 된다.
    "void 타입"은, 함수의 "리턴"이 없을 경우 나오는 타입이다.

 

10. 타입스크립트의 강력한 "타입 추론"

        let course = "React";

        course = 123  // error

    course 의 값을 "string" 으로 지정하고 "변수를 초기화"했다.
    그러므로, course 는 자동으로  "course:string" 이 된 것이다.
    그러므로 course 에 number 값인 123 을 넣으면 에러가 발생한다.

    이렇게, 초기화한 변수의 타입을 추론해, 적용시키는 것이, 타입스크립트의 큰 장점이자, 기능이다.

    타입스크립트는 이런식으로, 직접 명명 하기보단, "타입추론" 을 사용해, 처리 하는 것이 많다.
    다만 반드시 필요할 때에는 명명할 것이다.

 

 

Cannot redeclare block scoped variable [오류]

 

컴파일하면 동일한 이름의 .js 에 의해, 변수이름이 redeclare 되었다고 나온다.

    <시작>
        basic.ts 컴파일

    <결과>
        basic.ts
        basic.js (생성)

    <원인>
        그로인해, 둘이 한곳에 있는 파일로 여겨져
        basic.ts 의 변수가 redeclare 되었다고 나온다.

    <해결>
        1. 타입스크립트의 끝에 export { } 를 적는다. **

            function add(a: number, b: number) {
                return a + b;
            }

            const result = add(2, 3);

            export {};

        2. 혹은 둘중(xxx.ts , xxx.js) 하나의 이름을 변경한다.

 

댓글