# yarn을 사용하는 경우
yarn create react-app my-app --template typescript
# npx를 사용하는 경우
npx create-react-app my-app --template typescript
함수의 파라미터와 리턴값이 있다면 그에 대한 타입을 지정해줘야한다.
객체를 파라미터로 받는 함수라면 객체 내 속성들에 대한 타입도 지정해줘야한다.
1
function sum(a: number, b: number): number {
return a + b;
}
function objSum({ a, b }: { a: number; b: number }): string {
return `${a + b}`;
}
2
// Type Aliases (타입 별칭)
type Player = {
readonly name: Name,
age?: Age // ? 를 앞에 붙이면 optional
}
function playerMaker(name: string): Player{
return {
name
}
}
// 화살표 함수
const playerMaker = (name:string) : Player => ({
name
})
(JS 참고)
[화살표 함수 표현식]const func = (x) => x * x; // 간결한 본문 구문, 암시적 "반환"
간결한 본문 구문을 사용하여
return
을 명시하지 않고 값을 리턴할 때(params) => { object: literal }
을 사용하여 객체를 반환하면 예상대로 작동하지 않는다.
JS는 화살표 뒤에 오는 식이 왼쪽 중괄호가 아닌 경우에만 화살표 함수에 간결한 본문이 있는 것으로 간주한다.
이 문제를 해결하려면 객체를 괄호로 묶으면 된다.const func = () => ({ foo: 1 });
type Person = { id: number; age: number; height: number };
async function getPerson(): Promise<Person[]> {
const res = await fetch(`http://localhost:5008/people`);
if (!res.ok) {
throw new Error();
}
return res.json();
}
getPerson().then((res) => console.log(res[0]));
state 같은 경우 초기값에 따라 타입을 추론한다
타입을 명시하고 초기값을 설정하지 않으면 undefined도 포함되는 것이다.
import { useState } from "react";
function App() {
const [counter, setCounter] = useState<number>(1);
const increment = () => {
setCounter((prev) => prev++);
};
return <div onClick={increment}>{counter}</div>;
}
export default App;
import { useState } from "react";
function Parent() {
const [count, setCount] = useState("");
return <Child count={count}></Child>;
}
type Props = {
count: string;
};
function Child({ count }: Props) {
return <div>{count}</div>;
}
export default Parent;
PropsWithChildren을 제네릭으로 사용하면 undefined와 children을 둘 다 받을 수 있는 상태가 된다.
import { PropsWithChildren } from "react";
type BaseType = {
id: string;
};
function Child({ children }: PropsWithChildren<BaseType>) {
return <div>{children}</div>;
}
export function Parent() {
return (
<Child id="">
<div>chlidren</div> /* 옵셔널 */
</Child>
);
}
제네릭에 BaseType 을 넣어주기만 하면 바로 children props를 사용할 수 있다
이렇게 쓰면 BaseType + Children
을 자동으로 생성해준다.
그러나 PropsWithChildren
도 한가지 문제점이 있다.
그것은 PropsWithChildren
이 children 을 옵셔널 하게 갖는 다는 점이다.
그러므로 우리가 children 을 넘기지 않아도 아무런 오류를 뱉지 않는다.
그래서 PropsWithChildren
조차 명시적이지 않다는 위험성이 있어서
엄격하게 사용할 수 있는 방법도 있다.
import { ReactNode } from "react";
type BaseType = {
id: string;
};
// 타입 이름은 아무렇게나 지어도 됨
type StrictChildren<T> = T & { children: ReactNode };
function Child({ children }: StrictChildren<BaseType>) {
return <div>{children}</div>;
}
export function Parent() {
return (
<Child id="">
<div>chlidren</div>
</Child>
);
}
import {
AddressComponent,
PersonChildComponent,
ProfileComponent,
} from "./UtilityTypeChildren";
export type PersonProps = {
id: string;
description: string;
address: string;
age: number;
profile: string;
};
export const PersonComponent = ({
id,
description,
address,
age,
profile,
}: PersonProps) => {
return (
<>
<PersonChildComponent>
<div>{id}</div>
</PersonChildComponent>
<ProfileComponent
description={description}
address={address}
age={age}
profile={profile}
/>
<AddressComponent address={address} />
</>
);
};
import { PropsWithChildren, ReactNode } from "react";
import { PersonProps } from "./UtilityType";
export const PersonChildComponent = ({ children }: PropsWithChildren) => {
return <>{children}</>;
};
type OmitType = Omit<PersonProps, "id">; // ⭐️
export const ProfileComponent = ({
description,
address,
age,
profile,
}: OmitType) => {
return <></>;
};
type PickType = Pick<PersonProps, "address">; // ⭐️
export const AddressComponent = ({ address }: PickType) => {
return <></>;
};
Pick<T, K>
유틸리티 타입은 타입 T에서 K 속성들만 선택하여 새로운 타입을 만든다.Omit<T, K>
유틸리티 타입은 타입 T에서 K 속성들만 제외한 새로운 타입을 만든다!그 밖에 Partial<T>
Required<T>
Readonly<T>
등 다양한 유틸리티 타입이 있다.
이벤트를 사용할 때는 이벤트 핸들러의 타입을 지정해주면 된다.
import { useState, MouseEvent } from "react";
function App() {
const [counter, setCounter] = useState<number>(1);
const eventHandler = (e: MouseEvent<HTMLDivElement>) => {};
return <div onClick={eventHandler}>{counter}</div>;
}
export default App;