함수나 컴포넌트가 입력 타입에 따라 유연하게 동작하도록 만듬
function identity<T>(arg: T): T {
return arg;
}
identity<number>(10); // 반환 타입은 number
identity<string>("Hello"); // 반환 타입은 string
일반 함수뿐 아니라 화살표 함수에서도 동일하게 사용 가능.
const identity = <T>(arg: T): T => arg;
API 호출 시 응답 타입을 제네릭으로 지정해, 타입 오류를 사전에 방지 가능
import { useQuery } from '@tanstack/react-query';
type User = { id: number; name: string };
async function fetchUser(): Promise<User> {
const res = await fetch('/api/user');
return res.json();
}
const { data, isLoading } = useQuery<User>(['user'], fetchUser);
다양한 타입의 데이터를 처리할 수 있는 범용 UI 컴포넌트
type DropdownProps<T> = {
options: T[];
getLabel: (option: T) => string;
onSelect: (option: T) => void;
};
function Dropdown<T>({ options, getLabel, onSelect }: DropdownProps<T>) {
return (
<select onChange={(e) => onSelect(options[e.target.selectedIndex])}>
{options.map((o, i) => <option key={i}>{getLabel(o)}</option>)}
</select>
);
}
폼 구조가 달라져도 하나의 컴포넌트로 다양한 타입의 상태를 관리할 수 있습니다.
type FormProps<T> = {
initialValues: T;
onSubmit: (values: T) => void;
};
function Form<T>({ initialValues, onSubmit }: FormProps<T>) {
const [values, setValues] = useState<T>(initialValues);
return (
<form onSubmit={(e) => { e.preventDefault(); onSubmit(values); }}>
<button type="submit">Submit</button>
</form>
);
}
커스텀 훅에 제네릭을 적용하면 다양한 타입의 데이터를 안전하게 관리할 수 있습니다.
function useLocalStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(() => {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
});
const setValue = (value: T) => {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
};
return [storedValue, setValue] as const;
}
특정 조건을 만족하는 타입만 허용해 안전성
function getValue<T extends { id: number }>(item: T): number {
return item.id;
}
getValue({ id: 1, name: 'Apple' }); // ✅ OK
// getValue(123); // ❌ Error
제네릭 타입에 기본값을 설정해, 더 유연하게 사용할 수 있습니다.
type ApiResponse<T = any> = {
data: T;
error?: string;
};
const res: ApiResponse = { data: "test" }; // T는 any로 자동 설정
무조건 , 보다는
의도를 드러내는 이름
| ❌ Bad | ✅ Good |
|---|---|
| <T, U> | <Key, Value> |
| <T extends {}> |
type ButtonType = "primary" | "secondary";