This feels like so much achievable with TS, nevertheless, I couldn't.
This is my generic component interface:
export interface DataTableProps<T> {
data: {
id: string;
view: T;
}[];
cellModifications?: (
cellData: T[keyof T],
rowId: string,
) => {
[key: string]: TableCellProps & { // trying to find better typing here for key: string
content?: string | number | JSX.Element;
};
};
}
This is how I use it:
<DataTable<StatsFormatted>
data={list}
cellModifications={
(cellData, id) => ({
statName: {
align: 'center',
content: cellData,
},
})
}
/>
So the thing is, the object returned from cellModification callback has to include only the keys that are in the list passed to the data prop. I am trying to write a TS validation for that.
What I have tried so far are:
- I converted
[key: string]in the interface to[key in key of T]and that worked great, it started to validate. However, that expected all the fields in theTobject. That is not useful for my case, I only want to pass down some of them. - I also tried
[key in key of Partial<T>]. Problem with that is that even though it checks the properties againstTit still accepts any extra key. So still, not good. - Then, I tried this:
[key in StrictPropertyCheck<
T,
keyof Partial<PolicyStats['view']>,
'bad key'
>]
which uses this
export type StrictPropertyCheck<T, TExpected, TError> = T extends TExpected
? Exclude<keyof T, keyof TExpected> extends never
? T
: TError
: TExpected;
and this one actually did what exactly the first thing I have tried did and gave an error expecting all the fields in T.
Does anyone see what I am doing wrong? Here is a TS Playground example
Thank you!