npx create-react-app 프로젝트명 --template typescript
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
핵심: 컴포넌트 파일은 .tsx 확장자 사용 (JSX 문법 지원)
let 박스: JSX.Element = <div></div>;
let 버튼: JSX.Element = <button></button>;
type AppProps = {
name: string;
};
function App(props: AppProps): JSX.Element {
return <div>{props.name}</div>;
}
type ContainerProps = {
a: JSX.IntrinsicElements['h4'];
};
function Container(props: ContainerProps) {
return <div>{props.a}</div>;
}
// 사용법
<Container a={<h4>안녕</h4>} />
const [user, setUser] = useState<string | null>('kim');
// React에서는 <> 대신 as 사용
let code: any = 123;
let employeeCode = code as number; // ✅ 올바름
let employeeCode2 = <number>code; // ❌ React에서 금지
배열의 각 위치별로 정확한 타입 지정
let 멍멍이: [string, boolean];
멍멍이 = ['dog', true]; // ✅ 올바름
멍멍이 = [true, 'dog']; // ❌ 순서 틀림
function 함수(...x: [string, number]) {
console.log(x);
}
함수('kim', 123); // ✅ 가능
함수('kim', 123, 456); // ❌ 에러
type Num = [number, number?, number?];
let 변수1: Num = [10];
let 변수2: Num = [10, 20];
let 변수3: Num = [10, 20, 30];
let arr = [1, 2, 3];
let arr2: [number, number, ...number[]] = [4, 5, ...arr];
npm install redux react-redux
npm install @reduxjs/toolkit # 신규 방식 사용시
import { Provider } from 'react-redux';
import { createStore } from 'redux';
interface Counter {
count: number;
}
const 초기값: Counter = { count: 0 };
function reducer(state = 초기값, action: {type: string}) {
if (action.type === '증가') {
return { count: state.count + 1 };
} else if (action.type === '감소') {
return { count: state.count - 1 };
} else {
return state;
}
}
const store = createStore(reducer);
// Store 타입 export
export type RootState = ReturnType<typeof store.getState>;
import { useDispatch, useSelector } from 'react-redux';
import { Dispatch } from 'redux';
import { RootState } from './index';
function App() {
const 꺼내온거 = useSelector((state: RootState) => state);
const dispatch: Dispatch = useDispatch();
return (
<div>
{꺼내온거.count}
<button onClick={() => dispatch({type: '증가'})}>
버튼
</button>
</div>
);
}
import { createSlice, configureStore, PayloadAction } from '@reduxjs/toolkit';
const 초기값 = { count: 0, user: 'kim' };
const counterSlice = createSlice({
name: 'counter',
initialState: 초기값,
reducers: {
increment(state) {
state.count += 1;
},
decrement(state) {
state.count -= 1;
},
incrementByAmount(state, action: PayloadAction<number>) {
state.count += action.payload;
}
}
});
const store = configureStore({
reducer: {
counter1: counterSlice.reducer
}
});
export type RootState = ReturnType<typeof store.getState>;
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
import { useDispatch, useSelector } from 'react-redux';
import { RootState, increment } from './index';
function App() {
const 꺼내온거 = useSelector((state: RootState) => state);
const dispatch = useDispatch();
return (
<div>
{꺼내온거.counter1.count}
<button onClick={() => dispatch(increment())}>
버튼
</button>
</div>
);
}
let 음식: [string, number, boolean] = ['동서녹차', 4000, true];
let arr: [string, number, ...boolean[]] = ['동서녹차', 4000, true, false, true];
function 함수(...rest: [string, boolean, ...(number | string)[]]) {
// 첫째는 문자, 둘째는 boolean, 나머지는 숫자 또는 문자
}
함수('a', true, 6, 3, '1', 4);
function 함수(...rest: (string | number)[]): [string[], number[]] {
let result: [string[], number[]] = [[], []];
rest.forEach((a) => {
if (typeof a === 'string') {
result[0].push(a);
} else {
result[1].push(a);
}
});
return result;
}
// 사용 예시
함수('b', 5, 6, 8, 'a'); // [['b', 'a'], [5, 6, 8]]
.tsx 사용JSX.Elementas 키워드만 사용RootState export로 재사용PayloadAction<T> 사용 (신규 방식)