type Status = 'Active' | 'Pending' | 'Failed';
type User = {
name: string;
age: number;
status: 'active' // how to get autocomplete, it's lowercase??
} | {
error: string;
id: string;
status: 'failed' // can it be something like Status['Failed']
} |
{
id: string;
status: 'pending'
}
Given Status as string union type, sometimes there is need to use the type in another complex object type.
Different field structure for each status values.
How to make sure type safety when creating the User with status field?
I would like to reuse same type, something like below
const fooBarFn(status: Status) {
if (status === 'Pending') {
return {
id: '123',
status
}
}
// rest of fn
}
Are there any other patterns or best practices for the above?
some solution
type RecordX<K extends keyof any> = {
[P in K]: P;
};
type Status = 'Active' | 'Pending' | 'Failed';
type User<T extends RecordX<Status>> = { // how to default assign
name: string;
age: number;
status: T['Active']
} | {
error: string;
id: string;
status: T['Failed']
} |
{
status: T['Pending']
}
const user: User = { // need the template type parameter
name: 'foobar';
age: 99,
status: 'NotWorking' // not working
}
How to default the first generic parameter, so that user doesn't need to provide the type
status: Status?User, it will give you type completion if you have typed the other properties. See this example