EN VI

Typescript - Generic type with dynamic key?

2024-03-13 21:00:06
How to Typescript - Generic type with dynamic key

Given the following, the parameter value of the render method is typed as string | number.

How can I make sure that it gets typed as T[dataIndex], which is string?

type Col<T extends object, K extends keyof T = keyof T> = {
    title: string;
    dataIndex: K;
    render: (value: T[K]) => ReactNode;
};

function Tab<T extends object>(list: T[], cols: Col<T>[]): JSX.Element {
    return (
        <table>
            <thead>
                <tr>
                    {cols.map(col => (
                        <th key={col.title}>{col.title}</th>
                    ))}
                </tr>
            </thead>
            <tbody>
                {list.map((item, i) => (
                    <tr key={i}>
                        {cols.map(col => (
                            <td key={col.title} children={col.render(item[col.dataIndex])} />
                        ))}
                    </tr>
                ))}
            </tbody>
        </table>
    );
}

Tab(
    [
        { id: 1, name: 'Hello' },
        { id: 2, name: 'World' }
    ],
    [
        {
            title: 'Title',
            dataIndex: 'name',
            render: value => <span>{value}</span>
        }
    ]
);

Solution:

You need an extra type parameter to the component to capture the actual key that is being used:

function Tab<T extends object, K extends keyof T>(list: T[], col: Col<T, K>): JSX.Element {
//...
}

Playground Link

Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login