문자열 타입
문자열 값은 string으로 지정합니다.
const name: string = '홍길동'
React 프로젝트에서 바로 마주칠 가능성이 높은 TypeScript 문법과 패턴을 100개 예제로 정리한 원페이지입니다.
문자열 값은 string으로 지정합니다.
const name: string = '홍길동'
숫자 값은 number로 지정합니다.
const age: number = 30
참/거짓 값은 boolean입니다.
const active: boolean = true
문자열 배열은 string[]로 표현합니다.
const tags: string[] = ['React', 'TypeScript']
숫자 배열은 number[]입니다.
const scores: number[] = [90, 80, 100]
Array<T> 문법으로도 배열 타입을 만들 수 있습니다.
const users: Array<string> = ['철수', '영희']
순서와 타입이 고정된 배열은 tuple을 사용합니다.
const user: [string, number] = ['철수', 20]
값이 명시적으로 없음을 나타냅니다.
const selected: null = null
아직 값이 없음을 나타낼 수 있습니다.
const value: undefined = undefined
검사를 거의 하지 않는 타입이라 가급적 적게 사용합니다.
let data: any = '문자열'; data = 10
간단한 객체는 바로 타입을 작성할 수 있습니다.
const user: { name: string; age: number } = { name: '철수', age: 20 }
반복해서 쓸 객체 구조는 type으로 빼두면 좋습니다.
type User = { name: string; age: number }
객체 구조 선언에 interface도 자주 사용합니다.
interface User { name: string; age: number }
?가 붙으면 없어도 되는 속성입니다.
type User = { name: string; age?: number }
readonly 속성은 이후 변경을 막습니다.
type User = { readonly id: number; name: string }
객체 안의 객체도 타입을 지정합니다.
type User = { name: string; profile: { age: number; city: string } }
키 이름을 미리 모를 때 사용합니다.
type Scores = { [key: string]: number }
Record<K, V>는 키와 값 타입을 간단히 표현합니다.
type Scores = Record<string, number>
자주 쓰는 타입 조합에 이름을 붙일 수 있습니다.
type ID = string | number
기존 객체 구조를 확장할 수 있습니다.
interface Admin extends User { role: string }
함수 파라미터 타입을 지정합니다.
function add(a: number, b: number) { return a + b }
함수 반환값 타입도 명시할 수 있습니다.
function add(a: number, b: number): number { return a + b }
반환값이 없으면 void를 사용합니다.
function log(message: string): void { console.log(message) }
파라미터에도 ?를 붙일 수 있습니다.
function greet(name?: string) { return name ?? '손님' }
기본값이 있으면 호출 시 생략 가능합니다.
function greet(name: string = '손님') { return name }
콜백 함수 타입을 따로 선언할 수 있습니다.
type Calculate = (a: number, b: number) => number
함수를 파라미터로 받을 때 함수 모양을 지정합니다.
function run(callback: () => void) { callback() }
React 컴포넌트 onChange props에 자주 씁니다.
type OnChange = (value: string) => void
여러 개 인자를 배열로 받을 수 있습니다.
function sum(...nums: number[]) { return nums.reduce((a,b) => a+b, 0) }
입력 타입별 호출 형태를 여러 개 선언할 수 있습니다.
function format(value: string): string
function format(value: number): string
function format(value: string | number) { return String(value) }
둘 이상의 타입을 허용할 때 |를 사용합니다.
let id: string | number = 1
정해진 문자열만 허용할 수 있습니다.
type Size = 'sm' | 'md' | 'lg'
React 상태값에 특히 유용합니다.
type Status = 'idle' | 'loading' | 'success' | 'error'
typeof 검사 후 타입이 좁혀집니다.
if (typeof value === 'string') { console.log(value.toUpperCase()) }
객체 속성 존재 여부로 타입을 좁힐 수 있습니다.
if ('email' in user) { console.log(user.email) }
클래스 인스턴스 검사에도 타입 좁히기가 적용됩니다.
if (error instanceof Error) { console.log(error.message) }
공통 구분자 속성으로 안전하게 분기합니다.
type Result = { type:'success'; data:string } | { type:'error'; message:string }
모든 경우를 처리했는지 검사할 때 활용합니다.
function assertNever(x: never): never { throw new Error('unexpected') }
React에서 아직 데이터가 없을 때 매우 자주 씁니다.
const [user, setUser] = useState<User | null>(null)
값이 없을 수 있음을 타입에 포함할 수 있습니다.
type Props = { title: string | undefined }
중간 값이 null/undefined면 에러 대신 undefined를 반환합니다.
user?.profile?.name
null 또는 undefined일 때만 오른쪽 값을 사용합니다.
const label = value ?? '선택'
값이 반드시 있다고 개발자가 단언합니다. 남용은 피합니다.
inputRef.current!.focus()
개발자가 특정 타입이라고 명시합니다.
const input = event.target as HTMLInputElement
배열 값을 일반 string이 아니라 리터럴 타입으로 고정합니다.
const sizes = ['sm', 'md', 'lg'] as const
객체 타입의 키를 유니온 타입으로 얻습니다.
type UserKey = keyof User
실제 변수에서 타입을 추출합니다.
const config = { dark: true }; type Config = typeof config
객체 타입의 특정 속성 타입을 꺼냅니다.
type UserName = User['name']
삼항연산자 결과도 타입 검사를 받습니다.
const text: string = active ? 'ON' : 'OFF'
형태를 검사하면서 리터럴 타입 정보도 최대한 유지합니다.
const config = { mode: 'dark' } satisfies { mode: 'dark' | 'light' }
컴포넌트 props 구조를 타입으로 만듭니다.
type ButtonProps = { label: string }
function Button({ label }: ButtonProps) { return <button>{label}</button> }
없어도 되는 props는 ?를 붙입니다.
type ButtonProps = { disabled?: boolean }
문자열, JSX 등 다양한 children을 받을 때 사용합니다.
type CardProps = { children: React.ReactNode }
클릭 핸들러 같은 함수도 타입 지정합니다.
type Props = { onClick: () => void }
컴포넌트가 값을 부모로 올려줄 때 사용합니다.
type Props = { onChange: (value: string) => void }
허용 가능한 디자인 타입을 제한합니다.
type Props = { variant: 'primary' | 'secondary' }
기본 button 속성을 모두 받고 싶을 때 사용합니다.
type Props = React.ButtonHTMLAttributes<HTMLButtonElement>
기본 속성에 자체 props를 추가합니다.
type Props = React.ButtonHTMLAttributes<HTMLButtonElement> & { variant?: 'primary'|'outline' }
특정 HTML 태그의 props 타입을 가져옵니다.
type ButtonProps = React.ComponentProps<'button'>
이미 만든 컴포넌트의 props 타입을 재사용합니다.
type MyButtonProps = React.ComponentProps<typeof Button>
input의 change 이벤트 타입입니다.
function handleChange(e: React.ChangeEvent<HTMLInputElement>) { console.log(e.target.value) }
textarea 전용 이벤트 타입입니다.
React.ChangeEvent<HTMLTextAreaElement>
select 전용 이벤트 타입입니다.
React.ChangeEvent<HTMLSelectElement>
button 클릭 이벤트 타입입니다.
React.MouseEvent<HTMLButtonElement>
div 클릭 이벤트에도 요소 타입을 지정합니다.
React.MouseEvent<HTMLDivElement>
폼 submit 이벤트 타입입니다.
React.FormEvent<HTMLFormElement>
키보드 이벤트 타입입니다.
React.KeyboardEvent<HTMLInputElement>
focus/blur 이벤트 타입입니다.
React.FocusEvent<HTMLInputElement>
pointer 이벤트 타입입니다.
React.PointerEvent<HTMLButtonElement>
드래그앤드롭 이벤트 타입입니다.
React.DragEvent<HTMLDivElement>
초기값만으로 추론 가능하지만 명시할 수도 있습니다.
const [name, setName] = useState<string>('')
초기 null이면 실제 객체 타입을 함께 적습니다.
const [user, setUser] = useState<User | null>(null)
빈 배열은 타입을 명시하는 편이 안전합니다.
const [users, setUsers] = useState<User[]>([])
상태값을 제한할 수 있습니다.
const [status, setStatus] = useState<'idle'|'loading'>('idle')
DOM input을 참조할 때 사용합니다.
const inputRef = useRef<HTMLInputElement>(null)
div DOM 참조 타입입니다.
const boxRef = useRef<HTMLDivElement>(null)
타이머 ID 타입을 안전하게 저장합니다.
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
커스텀 훅 반환 구조도 타입 지정 가능합니다.
function useToggle(): [boolean, () => void] { ... }
useState setter 자체를 props로 넘길 때 사용합니다.
type Props = { setValue: React.Dispatch<React.SetStateAction<string>> }
useReducer는 action 타입을 명확히 만들면 좋습니다.
type Action = { type:'increment' } | { type:'reset' }
const [state, dispatch] = useReducer(reducer, initialState)
입력 타입을 그대로 반환할 수 있습니다.
function identity<T>(value: T): T { return value }
어떤 배열 타입에도 재사용할 수 있습니다.
function first<T>(items: T[]): T | undefined { return items[0] }
API 응답 구조를 재사용할 때 많이 씁니다.
type ApiResponse<T> = { data: T; success: boolean }
제네릭 자리에 실제 타입을 넣어 완성합니다.
type UserResponse = ApiResponse<User>
재사용 List 컴포넌트에 핵심적인 패턴입니다.
type ListProps<T> = { items: T[]; renderItem: (item:T) => React.ReactNode }
items 타입을 자동으로 따라가게 만들 수 있습니다.
function List<T>({ items, renderItem }: ListProps<T>) { return <>{items.map(renderItem)}</> }
특정 속성이 있는 타입만 허용할 수 있습니다.
function getId<T extends { id:number }>(item:T) { return item.id }
존재하는 키만 전달받게 할 수 있습니다.
function getValue<T, K extends keyof T>(obj:T, key:K) { return obj[key] }
비동기 함수 결과 타입을 지정합니다.
const fetchUser = async (): Promise<User> => { ... }
데이터 패칭 훅 구조를 제네릭화할 수 있습니다.
type QueryResult<T> = { data?: T; loading: boolean; error?: Error }
모든 속성을 선택적으로 만듭니다.
type UserForm = Partial<User>
모든 선택 속성을 필수로 만듭니다.
type FullUser = Required<User>
필요한 속성만 골라 새 타입을 만듭니다.
type UserPreview = Pick<User, 'name' | 'age'>
특정 속성을 제외합니다.
type NewUser = Omit<User, 'id'>
모든 속성을 readonly로 만듭니다.
type ReadonlyUser = Readonly<User>
유니온 타입에서 특정 값을 뺍니다.
type SmallSize = Exclude<Size, 'lg'>
유니온 타입에서 겹치는 값만 가져옵니다.
type LargeOnly = Extract<Size, 'lg' | 'xl'>
null과 undefined를 제거합니다.
type Name = NonNullable<string | null | undefined>
함수 반환 타입을 자동 추출합니다.
type Result = ReturnType<typeof createUser>
함수 파라미터 타입들을 튜플로 추출합니다.
type Args = Parameters<typeof add>