I have a type Response
type MainTypeResponse = {
message: 'OK' | 'ERROR';
error?: string;
}
If message = 'ERROR', then error
field is present.
Problem, when response is success (message = 'OK'). Error property does not present, and another properties is.
type SomeAnotherResponse = MainTypeResponse & {
prop1: 'string';
prop2: ''number;
}
I tried to union types (error)
type SomeAnotherResponse = MainTypeResponse | {
message: MainTypeResponse['message']
prop1: 'string';
prop2: ''number;
}
I don't want to condition it
prop1?: string
In code, i want to check it with this construction
const result: SomeAnotherResponse = '...'
if (result.message === 'OK') {
// ts error
console.log(result.prop1);
}
So, something like
type SomeAnotherResponse<T> = T extends {message: 'OK'} ? {} : {}
The simplest approach is to just define two separate types, and then create a union of those types. TypeScript will correctly narrow the type based on the value of the discriminator property:
type SuccessResponse = {
message: 'OK';
prop1: string;
prop2: number;
};
type ErrorResponse = {
message: 'ERROR';
error: string;
}
type MainResponse = SuccessResponse | ErrorResponse;
function handleResponse(response: MainResponse) {
if (response.message === 'OK') {
console.log(response.prop1); // OK
console.log(response.error); // Error
}
}
The handbook refers to this as a discriminated union.