ข้ามไปยังเนื้อหา

TypeScript with React

React component คือ function คุณจึง type component ด้วยการ type props นิยาม type (หรือ interface) สำหรับ props แล้ว annotate พารามิเตอร์:

type ButtonProps = {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary'; // optional, a literal union
};
function Button({ label, onClick, variant = 'primary' }: ButtonProps) {
return <button className={variant} onClick={onClick}>{label}</button>;
}

ให้ type props object ตรง ๆ (แบบข้างบน) แทน React.FC แบบเก่า — React.FC เลิกนิยมแล้ว (ทำให้ generics และการ type children ยุ่งยาก) แค่ annotate พารามิเตอร์ props ที่ destructure ก็พอ

เมื่อ component ครอบ content อื่น ให้ type children เป็น React.ReactNode — type “อะไรก็ตามที่ render ได้” ที่กว้างที่สุด:

type CardProps = {
title: string;
children: React.ReactNode; // JSX, strings, numbers, arrays, null…
};
function Card({ title, children }: CardProps) {
return <section><h2>{title}</h2>{children}</section>;
}

type อื่นที่จะใช้: React.ReactNode (content ที่ render ได้), React.ComponentProps<'button'> (ขโมย props ของ host element), และ React.CSSProperties (object style)

inference จัดการ hooks ส่วนใหญ่ให้ แต่ให้ type argument เมื่อค่าเริ่มต้นไม่ pin type:

const [count, setCount] = useState(0); // inferred: number
const [user, setUser] = useState<User | null>(null); // needs the annotation
const inputRef = useRef<HTMLInputElement>(null); // ref to a DOM node
const timer = useRef<number | undefined>(undefined); // ref to a mutable value

event handler ได้ event object ที่ถูก type ปล่อยให้ contextual typing infer แบบ inline เมื่อทำได้; annotate เมื่อแยก handler ออกมา:

function onChange(e: React.ChangeEvent<HTMLInputElement>) {
console.log(e.target.value);
}
<button onClick={(e) => e.preventDefault()}>Go</button> // e inferred as React.MouseEvent

จุด currency ที่ชัดเจน: ใน React 19 ref เป็น prop ธรรมดา สำหรับ function component คุณจึงไม่ต้องใช้ forwardRef และ generics ที่เก้ ๆ กัง ๆ ของตัวเองอีก type ref ไว้ข้าง ๆ props ตัวอื่นได้เลย:

// React 19 — ref is just a prop.
type InputProps = {
placeholder?: string;
ref?: React.Ref<HTMLInputElement>;
};
function TextInput({ placeholder, ref }: InputProps) {
return <input placeholder={placeholder} ref={ref} />;
}

forwardRef ยังทำงานได้ และ code เก่าที่ใช้ React.forwardRef<HTMLInputElement, Props> ก็ไม่มีปัญหา แต่สำหรับ component ใหม่ใน React 19 ข้าม forwardRef ไปได้เลย — wrapper น้อยลงหนึ่งชั้นและไม่ต้องเล่นกล generic

ควร type props ของ component อย่างไรใน React + TypeScript สมัยใหม่?
ใช้ type อะไรสำหรับ `children` ของ component?
เมื่อไรต้องส่ง type argument ให้ useState?
จัดการ ref บน function component ใน React 19 อย่างไร?