Trying to create status, subStatus type from an object.
The subStatus type is inferred from the status.
const APP_STATE = {
success: {
defaultX: {}
},
failed: {
apiError: {},
timeout: {}
}
}
type AppStateFn<T, U = keyof T> = {
status: U;
subStatus: keyof T[U]; // U not working
}
type AppState = AppStateFn<typeof APP_STATE>;
How to extract nested subStatus based on status from the object? This is required type
type AppStateManuallyTyped = {
status: 'success',
subStatus: 'defaultX'
} | {
status: 'failed',
subStatus: 'apiError' | 'timeout'
}
CodePudding user response:
I think this is what you want (playground):
const APP_STATE = {
success: {
defaultX: {}
},
failed: {
apiError: {},
timeout: {}
}
}
type AppStateFn<T extends object> = {
[key in keyof T]: {
status: key;
subStatus: keyof T[key];
};
}[keyof T];
type AppState = AppStateFn<typeof APP_STATE>;
Resulting type is:
type AppState = {
status: "success";
subStatus: "defaultX";
} | {
status: "failed";
subStatus: "apiError" | "timeout";
}
As to what is going on, first part of the type generates a type for each top-level property of input via mapped type, and that generated type consists of that top-level property (status: key;
) and all second-level properties (subStatus: keyof T[key];
). Afterwards, through means of indexed access type [keyof T]
extracts all resulting types and unionize them into single |
-expression.