javascript - Använda flera mappade typer för objektets nyckel/värden. Behöver bara ett värde från unionen?
Har lite problem med att få typen att fungera korrekt här.
Jag vill ange i ett objekt att varje toppnivånyckel är en av strängarna från en union, och värdet är ett inbäddat objekt som har nycklar av en av strängarna från en annan union, och dess värde kan vara strängen från den första unionen (typ som en tillståndsmaskin).
Ex :
type Status = 'idle' | 'loading' | 'error' | 'view'
type Actions = 'search' | 'search_success' | 'search_failure'
const app = {
idle: {
search: 'loading'
},
loading: {
search_success: 'view',
search_fail: 'error',
},
error: {
search: 'loading'
}
view: {
search: 'loading'
}
}
Mina försök att skriva detta har varit:
type States = { [key in Status]: { [key in Actions]: Status } };
Även om detta inte fungerar. Kan någon förklara hur jag skulle kunna använda några hjälptyper för att eventuellt tillåta att nyckeln i det nästlade objektet inte kräver ALLA värden från Actions-typen?
Tack!
Svar #1
Jag förenklade din kod lite.
Denna definition
type Status = 'idle' | 'loading'
type State = { [key in Status]: any}
är likvärdigt med
type State = {
idle: any;
loading: any;
}
Därför är följande kod ogiltig
const foo: State = {
idle: true
}
eftersom det saknar egenskapen loading.
En lösning - gör egenskaperna valfria
type Status = 'idle' | 'loading' | 'error' | 'view'
type Actions = 'search' | 'search_success' | 'search_failure'
type States = { [key in Status]?: { [key in Actions]?: Status } };
const app: States = {
idle: {
search: 'loading'
},
loading: {
search_success: 'view',
search_failure: 'error',
},
error: {
search: 'loading'
},
view: {
search: 'loading'
}
}
lekplats
Svar #2
Svaret från @MoshFeu ser ut att fungera bra, men eftersom jag har skrivit ner detta, publicerar jag det för att säga att du mer eller mindre kan få samma sak med en Partial:
type Status = 'idle' | 'loading' | 'error' | 'view'
type Actions = 'search' | 'search_success' | 'search_failure'
type States = { [key in Status]: Partial<{ [key in Actions]: Status }> };
const app: States = {
idle: {
search: 'loading'
},
loading: {
search_success: 'view',
search_failure: 'error',
},
error: {
search: 'loading'
},
view: {
search: 'loading'
}
};
