📚 Tutorial💻 ReactReact TSX

React TSX general types

Components

1. For general component

Hello.tsx
type HelloProps = {
    num: number;    // Must Have
    name?: string;  // Optional Props
 
    cbFunc: Function // Function as a types
 
    children?: ReactNode | ReactNode[]
 
    [x:string]: any; // Remaining Props (...rest) without actual types
}
 
export default function Hello({ num, name, cbFunc, children, ...rest }: HelloProps){
 
    const [ myAge, setMyAge ] = useState<number>(10);
 
    return (
        <>
        <h1>
            Hello {name || "Peter"} ({num})
        </h1>
 
        <button onClick={cbFunc} {...rest}>
            Active Me
        </button>
 
        {!!children && (
            <div>
                {children}
            </div>
        )}
 
        <button onClick={() => setMyAge(myAge + 1)}>
            Age + ({myAge})
        </button>
        </>
    )
}

2. For HTML component types

If you have to implement original HTML elements props and your props without ref

MyButton.tsx
type MyButtonProps = {
    name: string;
}
 
function MyButton({ name, ...rest }: MyButtonProps & React.ComponentPropsWithoutRef<"button">){
    return (
        <>
        <button {...rest}>
            123 {name}
        </button>
        </>
    )
}
    
export default MyButton

With Ref “React Ref”

MyButton.tsx
type MyButtonProps = {
    name: string;
}
 
function MyButton({ name, ref, ...rest }: MyButtonProps & React.ComponentProps<"button">){
    return (
        <>
        <button ref={ref} {...rest}>
            123 {name}
        </button>
        </>
    )
}
    
export default MyButton

3. Generic Components for input types

For generic input and output

Hello.tsx
type TestCompProps<T> = {
    data: T
    cbFunc: (data: T) => void
}
 
/** Generic Comp */
function TestComp<T,>({ data, cbFunc }: TestCompProps<T>) {
 
    function callCb() {
        cbFunc(data)
    }
 
    return (
        <>
            <button onClick={callCb}>
                Click
            </button>
        </>
    )
}
 
export default function Hello() {
    return (
        <>
            <TestComp
                data={"Peter"}
                cbFunc={(data) => console.log(data)}
            />
            {/* cbFunc: (data: string) => void */}
 
            <TestComp
                data={123}
                cbFunc={(data) => console.log(data)}
            />
            {/* cbFunc: (data: number) => void */}
            
            <TestComp
                data={true}
                cbFunc={(data) => console.log(data)}
            />
            {/* cbFunc: (data: boolean) => void */}
        </>
    )
}

4. Hinted string

For type reminder

Hello.tsx
type TestCompProps = {
    name: "Peter" | "Tom" | (string & {})
}
 
/** Hinted string with `(string & {})` */
function TestComp({ name }: TestCompProps) {
    return <h1>Hello {name}</h1>
}
 
export default function Hello() {
    return (
        <>
            {/* Will have hins "Peter" and "Tom" when you input name prop */}
            <TestComp name={"Tom"}/>
        </>
    )
}

5. Template literal type

For patterns types

Hello.tsx
type MyHello = `hello_${string}`
type Target = 'hello_A' | 'hello_B' | (MyHello & {})
 
type TestCompProps = {
    name: Target
}
 
/** Template literal type */
function TestComp({ name }: TestCompProps) {
    return <h1>Hello {name}</h1>
}
 
export default function Hello() {
    return (
        <>
            {/* OK */}
            <TestComp name={"hello_A"}/>
 
            {/* OK */}
            <TestComp name={"hello_Peter"}/>
 
            {/* NOT OK */}
            <TestComp name={"h123"}/>
        </>
    )
}