I did not find any information on Stack overflow or in existing issues so creating a new issue. Sorry if this is a duplicate.
I am not sure if this is a compiler limitation but this is what I am trying to achieve. I am creating a grid component that takes rows and columns. For example
interface Row {
field1: string;
field2: number;
}
interface Column<R> {
field: keyof R;
value: R[keyof R]; // This gives 'string | number '
}
Now if I create a columns array
const columns: Column<Row>[] = [
{ field: 'field1', value: 2 }, // There is not compilation error here which is expected because of 'R[keyof R]'
{ field: 'field2', value: 3 }
];
Is there a way I can modify value: R[keyof R] type so that in { field: 'field1', value: xyz } xyz can only be a string (Row['field1']).
Thanks.
To make it work you will need something like the following
interface Row {
field1: string;
field2: number;
}
interface Column<R, F extends keyof R = keyof R> {
field: F; // for Row as R produce the set: 'field1' | 'field2'
value: R[F]; // for Row as R produce the set: string | number
}
// for Row as R produce the set: Column<Row, 'field1'> | Column<Row, 'field2'>
type AnyRowField<R = Row, F extends keyof R = keyof R> = F extends keyof R ? Column<R, F> : never
And use it like this
// type checks
const columns: AnyRowField[] = [
{ field: 'field1', value: '2' },
{ field: 'field2', value: 3 }
]
// doesn't type check
const columns3: AnyRowField[] = [
{ field: 'field1', value: 2 }, // number not compatible with string
{ field: 'field2', value: '3' } // string not compatible with number
]
Example - https://bit.ly/2GG5nk2
Thank you so much. It worked perfectly.
Most helpful comment
To make it work you will need something like the following
And use it like this
Example - https://bit.ly/2GG5nk2