티스토리 뷰

reactJS

typescript 기초 + react 프로젝트 생성

코딩하는 둥아 2022. 2. 3. 11:00
728x90

https://react.vlpt.us/using-typescript/01-practice.html

https://react.vlpt.us/using-typescript/02-ts-react-basic.html

 

1. 타입스크립트 연습 · GitBook

01. 타입스크립트 연습 타입스크립트에서 가장 기본적인 것들을 연습해보겠습니다. 먼저 새로운 자바스크립트 프로젝트를 생성해보겠습니다. 터미널에서 다음 명령어들을 입력하세요. $ mkdir ts-

react.vlpt.us

위의 링크를 참고하여 정리한 게시물입니다. 🙂

 

 

함수의 파라미터들에 변수 타입을 지정해주고, 함수의 리턴값에 대한 타입을 지정해준다

아무것도 반환하지 않을 경우 함수의 타입은 void가 된다.

function sum(x:number, y:number) : number {
    return x+y;
}

function sumArray(numbers:number[]) : number {
    // reduce의 두번째 인자는 초기 시작값
    return numbers.reduce((previousValue, currentValue) => previousValue+currentValue, 0);
}

function returnNoting() : void {
    console.log('I am just saying hello world');
}

 

🥕 interface 사용하기

interface는 클래스 또는 객체를 위한 타입을 지정할때 사용되는 문법이다.

아래의 예시에서, Shape interface는 getArea라는 함수를 꼭 가져야하며, 반환값은 숫자임을 의미한다.

constructor를 사용하여 class가 가지는 변수의 값을 지정해 줄 수 있다.

interface Shape {
    getArea(): number; 
}   

class Circle implements Shape {
    radius : number;
    
    constructor(radius:number) {
        this.radius = radius;
    }

    getArea() {
        return this.radius * this.radius * Math.PI;
    }
}


class Rectangle implements Shape {
    width: number;
    height: number;

    constructor(width: number, height: number) {
        this.width = width;
        this.height = height;
    }

    getArea(): number {
        return this.width * this.height;
    }
}


const shapes: Shape[] = [new Circle(5), new Rectangle(10, 5)];

shapes.forEach(shape => {
    console.log(shape.getArea());
})

결과값

 

constructor의 파라미터에 public 또는 private accessor를 사용하면 width:number, height: number와 같이 하나 하나 설정해주는 작업을 생략할 수 있다.

public으로 선언된 값은 외부에서 직접 조회할 수 있지만, private으로 선언된 값은 클래스의 내부에서만 조회할 수 있다!

class Circle implements Shape {
    constructor(public radius:number) {
        this.radius = radius;
    }

    getArea() {
        return this.radius * this.radius * Math.PI;
    }
}


class Rectangle implements Shape {
    constructor(private width: number, private height: number) {
        this.width = width;
        this.height = height;
    }

    getArea(): number {
        return this.width * this.height;
    }
}

 

🥕 interface로 일반 객체 타입 설정하기

? 가 들어간 변수는 설정을 해도 되고 안해도 되는 값이라는 것을 의미한다.

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

interface Developer {
    name: string;
    age?: number;
    skills: string[];
}

const person: Person = {
    name: '최사람',
    age: 20
};

const expert: Developer = {
    name: '최개발',
    skills: ['javascript', 'react']
}

Person과 Developer의 형태가 매우 유사하므로 interface를 선언할 때 다른 interface를 extends 키워드를 사용하여 상속받자!

interface Developer extends Person{
    skills: string[];
}

 

🥕 type Alias 사용하기

type은 특정 타입에 별칭을 붙이는 용도로 사용된다. type을 사용하여 객체를 위한 타입을 생성할 수도 있다.

  • & 를 사용하여 두 개 이상의 타입을 합칠 수 있다.
  • Person[]을 people이라는 타입으로 사용할 수 있다.
interface Person {
    name: string;
    age?: number;
}

type Developer = Person & {
    skills: string[];
}

const person: Person = {
    name: '최사람',
};

const expert: Developer = {
    name: '최개발',
    skills: ['javascript', 'react']
}

type People = Person[];
const people: People = [person, expert];

🥕 Generics 사용하기

function merge(a: any, b: any): any {
  return {
    ...a,
    ...b
  };
}

const merged = merge({ foo: 1 }, { bar: 1 });

결과값이 any라는 것은 타입 유추가 꺠졌다는 것을 의미한다.

이런 상황에 Generics를 사용한다!

  function merge<A, B>(a: A, b: B): A & B {
    return {
      ...a,
      ...b
    };
  }

 

Generics을 사용하면 파라미터로 다양한 타입을 넣을 수 있고, 타입 지원을 지켜낼 수 있다.

  function wrap<T>(param: T) {
    return {
      param
    }
  }
  
  const wrapped = wrap(10);
  const wrapped2 = wrap('hello world');

 

🥕 interface에서 Generics 사용하기

  interface Items<T> {
    list: T[];
  }
  
  const items: Items<string> = {
    list: ['a', 'b', 'c']
  };

  const itemsNumber: Items<number> = {
    list: [1, 2, 3]
  };

🥕 type에서 Generics 사용하기

type Items<T> = {
  list: T[];
};

const items: Items<string> = {
  list: ['a', 'b', 'c']
};

 

🥕 리액트 컴포넌트 타입스크립트로 작성하기

function 키워드 vs React.FC

React.FC를 사용할 때 props의 타입을 Generics로 넣어서 사용한다.

  • defaultProps 제대로 작동하지 않음

App.tsx

import React from 'react';
import Greetings from './Greetings';

const App: React.FC = () => {
   const onClick = (name: string) => {
      console.log({name}, 'says hello');
   };
  return <Greetings name="Hello" onClick={onClick}/>;
};

export default App;

 

Greetings.tsx

defaultProps를 선언했지만 App.tsx에서 mark값이 없다면서 제대로 작동하지 않는다.

import React from 'react';

type GreetingsProps = {
    name: string;
    mark: string;
}

const Greetings: React.FC<GreetingsProps> = ({ name, mark }) => (
    <div>Hello, {name} {mark}</div>
);

Greetings.defaultProps = {
    mark: "!"
};

export default Greetings;

App.tsx에서 오류난 모습

React.FC를 생략한 Greetings.tsx

  • 생략을 하면 잘 작동하게 된다. defaultProps와 관련한 이슈 존재!
  • ? 문자를 사용하면 컴포넌트에 있어도 되고 없어도 되는 props를 의미한다.
  • 특정 함수를 props로 받는 경우 onClick처럼 타입 지정하기
import React from 'react';

type GreetingsProps = {
    name: string;
    mark: string;
    optional?: string;
    onClick: (name: string) => void;
}

//const Greetings = ({name, mark, optional}: GreetingsProps) => (
//   <div>Hello, {name} {mark}</div>
//)

function Greetings({name, mark, optional, onClick}:GreetingsProps) {
	const handleClick = () => {
        onClick(name);
    }
    
	return (
    	<div>
        	Hello, {name} {mark}
            {optional && <p>{optional}</p>}
            <div>
                <button onClick={handleClick}>Click Me</button>
            </div>
        </div>
    );
}

Greetings.defaultProps = {
    mark: "!"
};

export default Greetings;

결과 이미지

 

 

 

 

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함