I believe I've managed to use generics so that the DataPresentation component's searchKey prop can only be one of the values of field in columns
type Props<RowType extends AnyObject, ColType extends string> = {
columns: ReadonlyArray<{ readonly field: ColType }>;
rows: RowType[];
searchKey?: ColType;
};
const DataPresentation = <RowType extends AnyObject, ColType extends string>({
columns, rows, searchKey,
}: Props<RowType, ColType>) => { ... }
Here I am using the component:
export const playerPropsColumns = [
{ field: 'sportId' }, // todo: get sport name. from backend?
{ field: 'playerName' },
{ field: 'line' },
{ field: 'status' },
] as const;
// inside a component
<DataPresentation
columns={playerPropsColumns}
rows={data}
searchKey={'XXXXX'}
/>
That invalid searchKey passes the type check, but it's more interesting than simply "it's not working." When I hover over searchKey, its type is:
searchKey?: "line" | "sportId" | "playerName" | "status" | "XXXXX" | undefined
and playerPropsColumns's type is
columns: readonly {readonly field: "line" | "sportId" | "playerName" | "status" | "XXXXX"}[]
So it's getting the acceptable values from the playerPropsColumns array, but it's also accepting whatever I feed into searchKey which obviously completely defeats the point of type checking.
What's going on here and how do I fix it?
Note: I will say that all the read-only stuff is so I could use as const in my definition of the columns, so that I could do type FieldType = typeof playerPropsColumns[number]['field'];. However, after setting all this up and using generics I realize I of course didn't need that typedef at all, so maybe I can get rid of the read only stuff, and maybe they're the problem?