Advertisements
I would like to improve the type-checking of the following object:
interface Config {
fields: Record<string, unknown>;
table: { id: string }[];
}
const config: Config = {
fields: {
id: {}
},
table: [
{ id: 'id' },
{ id: 'name' },
]
};
The part I’m struggling with is that I want to type-check that the table
object id
should match a key in fields
. If table > id
is not present in fields
keys, then it should error. So:
{ id: 'id' }
is OK, sinceid
key exists infields
{ id: 'name' }
should error,name
key doesn’t exist infields
Is this possible? Plan B is to do this check at runtime.
>Solution :
It is not possible (yet) to create a standalone type
which can do validation like that. But generic type
s are powerful enough to achieve this. Generic types for validation are best used in combination with a function.
function useConfig<F>(config: { fields: F, table: { id: keyof F }[]}) {}
In this function we have the generic type F
which holds information about the object we pass with the fields
property. We can then use keyof F
inside table
.
Some tests to validate the result:
useConfig({
fields: {
id: {}
},
table: [
{ id: 'id' }
]
})
// works
useConfig({
fields: {
id: {}
},
table: [
{ id: 'id' },
{ id: 'name' }
]
})
// error
useConfig({
fields: {
id: {},
name: {}
},
table: [
{ id: 'id' },
{ id: 'name' }
]
})
// works