In this TypeScript example
type SomeType = "1" | "2" | "3" | "4" | "5" | "6" | "7";
type SomeStatus = "one" | "two" | "three" | "four" | "five" | "six" | "seven";
type TypeDiffer = {
type: "1"
} | {
type: Exclude<SomeType, "1">
}
type StatusDiffer = {
status: "one"
} | {
status: Exclude<SomeStatus, "one">
}
type OrderStatusFull = StatusDiffer & TypeDiffer;
const apiResponse: any = {};
const example: OrderStatusFull = {
type: apiResponse.type as SomeType,
status: apiResponse.status as SomeStatus
}
I've got the Typescript error:
Type '{ type: SomeType; status: SomeStatus; }' is not assignable to type 'OrderStatusFull'.
Type '{ type: SomeType; status: SomeStatus; }' is not assignable to type '{ status: "two" | "three" | "four" | "five" | "six" | "seven"; } & { type: "2" | "3" | "4" | "5" | "6" | "7"; } & { status: SomeStatus; }'.
Type '{ type: SomeType; status: SomeStatus; }' is not assignable to type '{ status: "two" | "three" | "four" | "five" | "six" | "seven"; }'.
Types of property 'status' are incompatible.
Type 'SomeStatus' is not assignable to type '"two" | "three" | "four" | "five" | "six" | "seven"'.
Type '"one"' is not assignable to type '"two" | "three" | "four" | "five" | "six" | "seven"'.
When I reduce number of types and statuses to 5 (or 3 and 7) it works. It works if multiplied number of items is up to 25.
type SomeType = "1" | "2" | "3" | "4" | "5"; // | "6" | "7";
type SomeStatus = "one" | "two" | "three" | "four" | "five"; // | "six" | "seven";
...
It also works with full list of types and statuses when I remove as SomeStatus
, but when I define apiResponse
more precisely, the problem is back.
const apiResponse: {
type: SomeType,
status: SomeStatus
} = {
type: "1",
status: "one"
}
const example: OrderStatusFull = {
type: apiResponse.type,
status: apiResponse.status
}
The only workaround is force type's or status's type to subset of the type, like this:
const example: OrderStatusFull = {
type: apiResponse.type as "1" | "2",
status: apiResponse.status
}
Can anyone explain why this happen and how to use type checking without workarounds?
The real world scenario is for example stock exchange api response, when based on order status and type combination different properties are filled.
Update: I've made stock exchange example in Playground. I omit the problem here, just to show which use cases I'm trying with union types in real life situations.