decho
dechoโ€ข8mo ago

Incorrect type inference with discriminated unions.

Hey folks, I am having a really weird issue. Here is a minimal reproducible example: https://tsplay.dev/WJB1kW Basically I have a function that returns an object of the Difference, which is a union of 3 other types:
interface DifferenceCreate {
type: "CREATE";
value: any;
}

interface DifferenceRemove {
type: "REMOVE";
oldValue: any;
}

interface DifferenceChange {
type: "CHANGE";
value: any;
oldValue: any;
}

export type Difference = DifferenceCreate | DifferenceRemove | DifferenceChange;

function myFunction(): Difference {
return { type: 'CREATE', value: 1 }
}
interface DifferenceCreate {
type: "CREATE";
value: any;
}

interface DifferenceRemove {
type: "REMOVE";
oldValue: any;
}

interface DifferenceChange {
type: "CHANGE";
value: any;
oldValue: any;
}

export type Difference = DifferenceCreate | DifferenceRemove | DifferenceChange;

function myFunction(): Difference {
return { type: 'CREATE', value: 1 }
}
I have created a router and a procedure that returns the result of myFunction. I then call this function on the client like this:
const test:Difference = await client.test.query();
const test:Difference = await client.test.query();
However, I am getting a type error:
Type '{ type: "CREATE"; value?: any; } | { type: "REMOVE"; oldValue?: any; } | { type: "CHANGE"; value?: any; oldValue?: any; }' is not assignable to type 'Difference'.
Type '{ type: "CREATE"; value?: any; }' is not assignable to type 'Difference'.
Type '{ type: "CREATE"; value?: any; }' is not assignable to type 'DifferenceCreate'.
Property 'value' is optional in type '{ type: "CREATE"; value?: any; }' but required in type 'DifferenceCreate'.
Type '{ type: "CREATE"; value?: any; } | { type: "REMOVE"; oldValue?: any; } | { type: "CHANGE"; value?: any; oldValue?: any; }' is not assignable to type 'Difference'.
Type '{ type: "CREATE"; value?: any; }' is not assignable to type 'Difference'.
Type '{ type: "CREATE"; value?: any; }' is not assignable to type 'DifferenceCreate'.
Property 'value' is optional in type '{ type: "CREATE"; value?: any; }' but required in type 'DifferenceCreate'.
Any idea how to solve this issue?
tsplay.dev
A link shortener for the TypeScript Playground
Solution:
GitHub
bug: Incorrect type inference with discriminated unions. ยท Issue #5...
Provide environment information System: OS: Linux 6.5 Linux Mint 21.2 (Victoria) CPU: (24) x64 AMD Ryzen 9 7900 12-Core Processor Memory: 24.78 GB / 30.53 GB Container: Yes Shell: 5.8.1 - /bin/zsh ...
Jump to solution
9 Replies
Nick
Nickโ€ข8mo ago
Hey could you please put this in a GitHub issue? Fantastic reproduction ๐Ÿ™‚
decho
dechoโ€ข8mo ago
for sure I can, I just thought I might be doing something wrong so didn't want to create a useless issue
Nick
Nickโ€ข8mo ago
All looks sane to me, we might be able to improve this
decho
dechoโ€ข8mo ago
all right, i will do it in a few min, do you think the title is good enough? as in, is it descriptive enough, right terminology and all?
Solution
decho
dechoโ€ข8mo ago
GitHub
bug: Incorrect type inference with discriminated unions. ยท Issue #5...
Provide environment information System: OS: Linux 6.5 Linux Mint 21.2 (Victoria) CPU: (24) x64 AMD Ryzen 9 7900 12-Core Processor Memory: 24.78 GB / 30.53 GB Container: Yes Shell: 5.8.1 - /bin/zsh ...
Alex / KATT ๐Ÿฑ
Alex / KATT ๐Ÿฑโ€ข8mo ago
ah, this is something to do with the SerializeJson we use
Alex / KATT ๐Ÿฑ
Alex / KATT ๐Ÿฑโ€ข8mo ago
you can see this works https://tsplay.dev/mxzyZw
TS Playground - An online editor for exploring TypeScript and JavaS...
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.
Alex / KATT ๐Ÿฑ
Alex / KATT ๐Ÿฑโ€ข8mo ago
oops, i missed that there was replies ๐Ÿ™‚
decho
dechoโ€ข8mo ago
hey man I left a reply in the github issue, but just wanted to say thanks to both of you for helping out, i appreciate it ๐Ÿ‘