1. IDE 를 더욱 더 적극적으로 활용 (자동완성, 타입확인)
2. 실수방지
tsc 명령어를 입력해서 컴파일
기본 타입
let count: number = 0;
const message: string = 'hello world'; // 문자열
const done: boolean = true; // 불리언 값
const numbers: number[] = [1, 2, 3]; // 숫자 배열
const messages: string[] = ['hello', 'world']; // 문자열 배열
let mightBeUndefined: string | undefined = undefined; // string 또는 undefined
let nullableNumber: number | null = null; // number 또는 null
// 값까지 제한 할 수 있다?
let color: 'red' | 'orange' | 'yellow' = 'red'; // red, orange, yellow 중 하나
함수 타입
// 일반 함수
// 파라미터 타입 // 반환 값 타입
function sum(x: number, y: number): number {
return x + y;
}
sum(1, 2);
// 화살표 함수
let corsURL = (url:string): string => `https://crossorigin.me/${url}`;
타입스크립트를 사용하면 함수실행 코드를 작성할 때, 함수의 파라미터로 어떤 타입을 넣어야 하는지 바로 알 수 있다
%208dff14bfb1f641e28ae4d00cd19d7be7/Untitled.png)
배열의 내장함수를 사용 할 때에도 타입 유추가 매우 잘 이루어진다
%208dff14bfb1f641e28ae4d00cd19d7be7/Untitled%201.png)
반환 값이 없다면 반환 타입을 void 로 설정
function returnNothing(): void {
console.log('I am just saying hello world');
}
클래스와 관련된 타입의 경우엔 interface, 일반 객체의 타입의 경우엔 그냥 type을 사용해도 무방하다
객체를 위한 타입을 정의할때 무엇이든 써도 상관 없는데 일관성 있게만 쓰면 된다
클래스 또는 객체를 위한 타입을 지정 할 때 사용되는 문법
일반 객체를 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']
};
interface를 선언 할 때 extends 키워드를 사용하면 다른 interface를 상속받아 사용할 수 있다
interface Person {
name: string;
age?: number; // 물음표가 들어갔다는 것은, 설정을 해도 되고 안해도 되는 값이라는 것을 의미합니다.
}
// 오버라이딩x
interface Developer extends Person { // Person의 설정을 가져가는~
skills: string[];
}
const person: Person = {
name: '김사람',
age: 20
};
const expert: Developer = {
name: '김개발',
skills: ['javascript', 'react']
};
const people: Person[] = [person, expert]; // 요소가 Person객체 type인 배열? 뭐지이게
type 은 특정 타입에 별칭을 붙이는 용도로 사용type Person = {
name: string;
age?: number; // 물음표가 들어갔다는 것은, 설정을 해도 되고 안해도 되는 값이라는 것을 의미합니다.
};
// & 는 Intersection 으로서 두개 이상의 타입들을 합쳐줍니다.
// extend와 같은 역할
// &는 a도 b도 존재
// 오버라이딩o
type Developer = Person & {
skills: string[];
};
const person: Person = {
name: '김사람'
};
const expert: Developer = {
name: '김개발',
skills: ['javascript', 'react']
};
type People = Person[]; // Person[] 를 이제 앞으로 People 이라는 타입으로 사용 할 수 있습니다.
const people: People = [person, expert];
type Color = 'red' | 'orange' | 'yellow';
const color: Color = 'red';
const colors: Color[] = ['red', 'orange'];
여러 종류의 타입에 대하여 호환을 맞춰야 하는 상황에서 사용하는 문법
함수에서 Generics 사용하기
// 함수 이름 옆에 <>를 쓰고 안에 임의의 타입을 설정해서 사용한다
function merge<A, B>(a: A, b: B): A & B {
return {
...a,
...b
};
}
const merged = merge({ foo: 1 }, { bar: 1 });
iterface / type에서 Generics 사용하기
interface Items<T, N> { // <>안에 임의의 타입을 설정한다
list: T[]; // 필요한 곳에 적용한다
}
const items: Items<string, number> = { // <>안에 사용할 타입을 적는다
list: ['a', 'b', 'c']
};
---
type Items<T> = {
list: T[];
};
const items: Items<string> = {
list: ['a', 'b', 'c']
};
뒤에 --typescript 가 있으면 타입스크립트 설정이 적용된 프로젝트가 생성된다
npx create-react-app ts-react-tutorial --typescript
props객체의 타입을 지정해준다
type GreetingsProps = {
name: string;
mark: string;
optional?: string; // 있어도,없어도 되는 props에는 옵셔널을 붙여준다
onClick: (name: string) => void; // 함수일 경우의 타입 지정 방법(파라미터의 타입, 반환 값의 타입)
};
import React from 'react';
import logo from './logo.svg';
import './App.css';
// 화살표 함수로 지정 + React.FC라는 type사용
const App: React.FC = () => {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
import React from 'react';
type GreetingsProps = {
name: string;
//children지정하지 않아도 자동으로 들어가 있음
};
// 파라미터(props)의 타입을 Generics로 넣어서 사용
const Greetings: React.FC<GreetingsProps> = ({ name }) => (
<div>Hello, {name}</div>
);
export default Greetings;
React.FC 를 사용 할 때의 이점
props 에 기본적으로 children 이 들어가있다
%208dff14bfb1f641e28ae4d00cd19d7be7/Untitled%202.png)
단점
children 이 옵셔널 형태로 들어가있다보니, 컴포넌트의 타입 지정이 완벽하지 않은 문제가 있다 → 결국에는 따로 타입을 지정해야 함type GreetingsProps = {
name: string;
children: React.ReactNode;
};defaultProps 가 제대로 작동하지 않는다React.FC 를 사용하지 않았을 경우
회살표 함수
import React from 'react';
type GreetingsProps = {
name: string;
mark: string;
};
const Greetings = ({ name, mark }: GreetingsProps) => (
<div>
Hello, {name} {mark}
</div>
);
Greetings.defaultProps = {
mark: '!'
};
export default Greetings;
일반함수
import React from 'react';
type GreetingsProps = {
name: string;
mark: string;
};
function Greetings({ name, mark }: GreetingsProps) {
return (
<div>
Hello, {name} {mark}
</div>
);
}
Greetings.defaultProps = {
mark: '!'
};
export default Greetings;
질문
컴포넌트일 경우 반환 값의 타입을 지정하지 않는건가?
useState를 사용 할 때 Generics 를 사용하지 않아도 알아서 타입을 유추하기 때문에 생략해도 상관없지만
상태가 null일 수도 있고 아닐수도 있을때 Generics 를 활용하면 좋다
type Information = { name: string; description: string };
const [info, setInformation] = useState<Information | null>(null);
// state가 Information이라는 객체 타입일수도, null일 수도 있다
질문
const [count, setCount] = useState<number>(0); // 그냥 number타입을 쓰면 되는 거 아닌가?
이벤트를 다룰 때의 타입 지정 방법
event객체의 타입은 ? 커서를 onChange 에 올리면 나온다
%208dff14bfb1f641e28ae4d00cd19d7be7/Untitled%203.png)
import React, { useState } from 'react';
// props객체의 타입을 지정한다
type MyFormProps = {
onSubmit: (form: { name: string; description: string }) => void;
};
function MyForm({ onSubmit }: MyFormProps) { //props을 꺼내 쓸 때 만들어둔 props타입 이름을 적는다
const [form, setForm] = useState({
name: '',
description: ''
});
const { name, description } = form;
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
};
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
};
return (
<form onSubmit={handleSubmit}>
<input name="name" value={name} onChange={onChange} />
<input name="description" value={description} onChange={onChange} />
<button type="submit">등록</button>
</form>
);
}
export default MyForm;
import React, { useReducer } from 'react';
// 액션 값 자체를 전부 타입으로 지정해놓는다?
type Action = { type: 'INCREASE' } | { type: 'DECREASE' };
// type외에 다른 값도 있는 경우 -> type을 사용자가 지정할 수도 있다?
type Action =
| { type: 'SET_COUNT'; count: number }
| { type: 'SET_TEXT'; text: string }
| { type: 'SET_COLOR'; color: Color }
| { type: 'TOGGLE_GOOD' };
function reducer(state: number, action: Action): number {
switch (action.type) {
case 'INCREASE':
return state + 1;
case 'DECREASE':
return state - 1;
default:
throw new Error('Unhandled action');
}
}
function Counter() {
const [count, dispatch] = useReducer(reducer, 0);
const onIncrease = () => dispatch({ type: 'INCREASE' });
const onDecrease = () => dispatch({ type: 'DECREASE' });
return (
<div>
<h1>{count}</h1>
<div>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
</div>
);
}
export default Counter;