typescript - Validera egenskap baserat på nycklar från en annan egenskap
Jag skulle vilja förbättra typkontrollen av följande objekt:
interface Config {
fields: Record<string, unknown>;
table: { id: string }[];
}
const config: Config = {
fields: {
id: {}
},
table: [
{ id: 'id' },
{ id: 'name' },
]
};
Den del jag har svårt med är att jag vill typkontrollera att table-objektets id ska matcha en nyckel i fields. Om table > id inte finns bland fields-nycklarna, så ska det ge ett fel. Så:
{ id: 'id' }är OK, eftersomid-nyckeln finns ifields{ id: 'name' }borde ge ett fel,name-nyckeln finns inte ifields
Är detta möjligt? Plan B är att göra denna kontroll vid körning.
Svar #1
Det är inte möjligt (ännu) att skapa en fristående type som kan göra validering på det sättet. Men generiska type är tillräckligt kraftfulla för att uppnå detta. Generiska typer för validering används bäst i kombination med en funktion.
function useConfig<F>(config: { fields: F, table: { id: keyof F }[]}) {}
I denna funktion har vi den generiska typen F som innehåller information om objektet vi skickar med fields-egenskapen. Vi kan sedan använda keyof F inuti table.
Några tester för att validera resultatet:
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
Lekplats
Svar #2
type fieldsType = {id:any}
const config:{fields:fieldsType, table:{[k:string]:keyof fieldsType}[]} = {
fields: {
id: {},
},
table: [
{ id: 'id' },
{ id: 'name' },
]
};
