본문 바로가기

Frontend Study

[유데미x스나이퍼팩토리] Next.js 3기 - 사전직무교육 2일차

타입 오퍼레이터

타입스크립트에서는 인터섹션 연산자, 유니온 연산자 등을 사용 할 수 있음

  • 인터섹션 연산자 ⇒ &
    • 자바스크립트의 && (and)와 같음
    • 여러개의 타입 정의를 하나로 합칠 때 사용
  • 유니온 연산자 ⇒ |
    • 자바스크립트의 || (or)과 같음
    • 여러개의 타입을 매개변수로 받을 수 있게 함
    • 유니온 연산자를 사용하는 매개변수간의 연산은 에러가 발생 할 수 있음
//인터섹션 연산자
interface name {
	name: string
}
interface age {
	age: number
}

const inter = (obj: name & age) => console.log(obj)
inter({name: 'john', age: 20}) //name: john, age: 20
inter({name: 'song'}) //에러 발생 -> age 속성이 없음

//유니온 연산자
const union = (value: string | number) => console.log(value)
union(10) //10
union('A') //A

// 유니온 연산자를 사용하는 매개변수간 연산 에러
const add = (n1: number, n2: number|string) => console.log(n1 + n2)
// n1은 number지만, n2가 string인 경우엔 에러 발생 => typeof를 통해 조건부 연산 필요

타입 추론

타입스크립트는 변수에 할당된 값을 바탕으로 타입을 자동으로 추론 할 수 있음.

일부 타입은 굳이 설정해주지 않아도 자동으로 타입이 지정됨

let num = 10;
let str = "STRING";
  • 코드가 간결해지고 가독성이 높아지지만 변수의 타입을 직관적으로 알기 힘들다

리터럴 타입

값을 타입으로 설정하는 방식

let num: 10 = 10;
//num에는 10이라는 값밖에 들어 갈 수 없음

const 키워드로 변수를 선언할 경우, 자동으로 리터럴 타입으로 선언됨

→ const는 재할당이 불가능하기 때문

let str1 = "A"; // string
const str2 = "A"; // 'A'

함수 오버로드

함수가 여러 타입의 매개변수를 가지거나, 필요로 하는 매개변수의 개수가 다를 경우, 각 타입별로 리턴 타입을 구분해주는 방법

→ 각 케이스별로 함수를 선언해줌으로써 사용 가능

//오버로딩
function add(n1: number, n2: number): number; //매개변수가 number일 경우 number 리턴
function add(n1: string, n2: string): string; //매개변수가 string일 경우 string 리턴
// 위 하나하나의 선언문을 오버로드 시그니처라고 함

function add(n1: number | string, n2: number | string): number | string {
  return n1 + n2;
}

// 매개변수의 개수가 다른 경우
function multiple(n1: number): number;
function multiple(n1: number, n2: number): number;
function multiple(n1: number, n2?: number, n3?: number): number;

function multiple(n1: number, n2?: number, n3?: number) {
  return n1 * (n2 ?? 1) * (n3 ?? 1);
}

타입 얼리어스(타입 별칭)

타입에 별칭을 지어주는 것 → 타입에 대치 할 만한 이름을 붙여주는 것

  1. type : type 키워드를 이용해 새로운 타입을 만들어 줌
type Str = string;
type Num = number;

const name: Str = "john";
const age: Num = 20;
const gender: Num = "male"; //에러 발생

type User = {
  name: string;
  age: number;
  isMale: boolean;
};

const printInfo = (user: User) => {
  console.log(`name: ${user.name} / age: ${user.age} / isMale: ${user.isMale}`);
};

printInfo({
  name: "song",
  age: 28,
  isMale: true,
});
// name: song / age: 28 / isMale: true

//함수에도 적용 가능
type AddNumber = {
  (n1: number, n2: number): number;
};

const addNum: AddNumber = (n1, n2) => n1 + n2;
console.log(addNum(10, 20)); //30

  1. 인터페이스
interface User {
  name: string;
  age: number;
  gender: "male" | "female";
}

const user1: User = {
  name: "jack",
  age: 30,
  gender: "male",
};

const user2: User = {
  name: "laura",
  age: 25,
  gender: "female",
};

  • 인터페이스는 병합 가능
    • 같은 이름으로 인터페이스를 선언하면 자동으로 병합됨
// interface 병합
interface User {
  name: string;
  age: number;
}

interface User {
  gender: "male" | "female";
}

const user1: User = {
  name: "jack",
  age: 30,
  gender: "male",
};

const user2: User = {
  name: "laura",
  age: 25,
  gender: "female",
};

  • 인터페이스는 상속 역시 가능
    • 상속받은 인터페이스의 속성들 역시 반드시 포함해야 함
interface User {
  name: string;
  age: number;
  gender: "male" | "female";
}

//User를 상속한 인터페이스 Student
interface Student extends User {
  grade: number;
}

const user1: Student = {
  name: "jack",
  age: 19,
  gender: "male",
  grade: 3
};

const user2: Student = {
  name: "laura",
  age: 17,
  gender: "female",
  grade: 1
};

비교

type interface

  type interface
사용되는 자료형 기본 자료형, 객체 객체
툴팁 속성 타입 표시 interface라고만 표시
병합 불가능 가능
상속(확장) 불가능 가능

Enum

enum은 열거형을 정의하는데 사용되는 데이터 타입

  1. 숫자 열거형지정하면 해당 수로부터 1씩 증가
  2. 따로 지정하지 않을시 0부터 자동으로 할당
enum Direction {
  Up,
  Down,
  Left,
  Right,
}

console.log(Direction.Up); // 0
console.log(Direction.Down); // 1
console.log(Direction.Left); // 2
console.log(Direction.Right); // 3

enum Direction {
  Up,
  Down = 10,
  Left,
  Right,
}

console.log(Direction.Up); // 0
console.log(Direction.Down); // 10
console.log(Direction.Left); // 11
console.log(Direction.Right); // 12
  1. 문자 열거형
  2. 문자 열거형은 반드시 값을 지정해줘야 함
enum Color{
	R: 'red',
	G: 'green',
	B: 'blue'
}

console.log(Color.R) // 'red'
console.log(Color.G) // 'green'
console.log(Color.B) // 'blue'

제네릭

타입을 미리 지정하지 않고 사용하는 시점에서 타입을 지정해 사용 → 타입을 함수의 매개변수처럼 사용

function getValue<T>(value: T) { //T를 변수처럼 사용
  console.log(value);
}
getValue<number>(10); // T 자리에 number가 들어감
getValue<string>("A"); // T 자리에 string이 들어감

//화살표함수
const getValue = <T>(value: T) => console.log(value);

//인터페이스
interface User<T> {
  name: string;
  age: number;
  gender: T;
}

const user1: User<string> = {
  name: "jack",
  age: 30,
  gender: "male",
};

const user2: User<number> = {
  name: "lauren",
  age: 30,
  gender: 2,
};

React 프로젝트 생성

  1. npx create-react-app
    • 더이상 업데이트가 되지 않는 구식 프로젝트 생성법
    • cra로는 프로젝트 생성을 지양
  2. npm create vite@latest
    • 최신 프로젝트 생성법
    • 프레임워크 선택 → react
    • 개발 언어 및 컴파일러 선택
      • Javascript or Typescript
      • SWC (Speed Web Compiler) 옵션 선택 → 최신 웹 컴파일러
    • npm install로 패키지 설치 후 npm run dev로 실행

NPM / NPX / YARN

  1. npm
    • npm은 node.js의 기본 패키지 관리자
  2. npx
    • node 패키지를 설치하는 도구npx
    • npm을 통해 로컬 또는 Global로 다운받지 않은 패키지도 일회성으로 설치 할 수 있음

React Remind

프로젝트 시작

  1. 터미널에 npm run dev를 입력하면 ‘vite’ 명령어 실행
  2. vite 내부 개발 서버 실행
  3. index.html의 내용 파싱
  4. main.tsx 스크립트 실행 → root라는 id를 가진 div를 렌더
  5. root 아래에 App.tsx를 렌더하며 화면을 보여줌

클래스형 컴포넌트와 함수형 컴포넌트

  • 클래스형 컴포넌트는 문법이 어렵고 복잡
  • React Hook 등장 이후 함수형 컴포넌트에서도 상태 관리가 가능해짐
  • ⇒ 클래스형 컴포넌트가 사장된 원인
// 클래스형 컴포넌트
import { Component } from "react";
interface AppProps {}
interface AppState {
  count: number;
}
class App extends Component<AppProps, AppState> {
  constructor(props: AppProps) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  render() {
    return <h1>Hello, Create Element!</h1>;
  }
}
export default App;

//함수형 컴포넌트
import react from "react"

//함수 선언문 (export default 한번에 쓸 수 있음)
export default function App(){
	return <h1>Hello, Create Element!</h1>;
};

//함수 표현식(화살표 함수) (export default를 따로 써줘야 함)
const App = () => {
	return <h1>Hello, Create Element!</h1>;
};
export default App

컴포넌트 작성 규칙

  1. 루트 태그는 하나만 사용해야 함
// O
export default function App(){
	return (
		<h1>Hello, Create Element!</h1>
	);
};

// X
export default function App(){
	return (
		<h1>Hello, Create Element!</h1>
		<h1>Hello, Create Element!</h1>
	);
};

// 빈 태그로라도 하나의 태그로 묶어줘야 한다
export default function App(){
	return (
		<>
			<h1>Hello, Create Element!</h1>
			<h1>Hello, Create Element!</h1>
		</>
	);
};
  1. 태그는 반드시 닫아야 함
// O
export default function App(){
	return (
		<div></div>
	);
};

// O
export default function App(){
	return (
		<div />
	);
};

// X
export default function App(){
	return (
		<div>
	);
};
  1. 표현식은 { } 사용
// O
export default function App() {
  const str = "hi";
  return <h1>{str}</h1>;
}

// X
export default function App() {
  return (
    <h1>str</h1> // "hi"가 아니라 "str"이 출력됨
  );
}
  1. class 대신 className
// O
export default function App() {
  const str = "hi";
  return <h1 className="title">{str}</h1>;
}

// X
export default function App() {
  return <h1 class="title">{str}</h1>;
}
  1. 컴포넌트명은 대문자로
// O
export default function App() {
  const str = "hi";
  return <div />;
}

// X
export default function app() {
  return <div />;
}

본 게시글의 예제 코드는 수코딩(https://www.sucoding.kr)을 참고했습니다