Typia runtime validation fails on intersections of discriminated union types
Bug Report
📝 Summary
Write a short summary of the bug in here.
- Typia Version: 9.3.1-dev.20250520
- Expected behavior: Ability to validate union types containing complex types
- Actual behavior: Fails with false positive errors
I am trying to validate an instance of PartyWithRole in the following type hierarchy:
type PartyWithRole = Party & PartyRoleInfo;
type Party = Individual | Corporation;
interface Individual {
type: "individual";
birthDate: Date;
}
interface Corporation {
type: "corporation";
}
type PartyRoleInfo = { partyRole: "customer" } | {
partyRole: "other"
otherPartyRole: string
}
But I run into issues where typia seems unable to validate the partyRole property.
I am not sure what the actual problem stems from, but it seems to only occur if I have a non-primitive property in the heirarchy (in this case, I kept the birthDate property).
Note: I have trimmed away most of the properties in my actual type hierarchy here to try and create the smallest example possible that still exhibits the issue.
⏯ Playground Link
Here is a link that demonstrates the issue:
https://typia.io/playground/?script=JYWwDg9gTgLgBDAnmYBDOAzKERwERIqp4DcAUGQMYQB2AzvMDQCbABuwzArqgDZwBeOAG8ycfIQCmeAFz4mrDtz54ANGPwAjYLAAWAEVQxpcmpIDucQ8YAUASnXi8YVLEQAlCLxP4IMXZJQahp4fgFQAAquSJ7eshJ+fLyIcGx8nHAMUEwA5sEAvhRScFFugnAAkizsnDz8AD5wAMLQkFBGwLTkxaVIAOrA-rGS5b0pAGQl0R5eklUYEORkTMZQGKiUI1WKtXwiGlJyeAo1yrykGtp61pJyNyRwAPSPcADVALTvcADKkpIgdAQEDgmhG-hG2D8cEoqC4dBGEAwCACcGAdDoXEkqhBXHgzAgkjoNAA5PANjA6skENkcjlAnAwNhNN5cOZBroILi4FwaJ0aAhkCNhvMIGRCssaKt1ptmq1oB1aPtxId8NQoG0FTQLuKetNhTQFuVhAy9bMjpQ4TAcIE8HB8nBGqJxC43MMjmEbRoPZFTd45FlcmKKNR6PA0rxOJr3ISuLx4EJCGgAHThyPGAA8YwGQ1mAD4bCclHU7OQQ3RZkneBAcjZU8wozG4yWgA
💻 Code reproducing the bug
import typia from "typia";
const individual: PartyWithRole = {
"type": "individual",
"birthDate": new Date(),
"partyRole": "other",
"otherPartyRole": "some-valid-string",
}
type PartyWithRole = Party & PartyRoleInfo;
type Party = Individual | Corporation;
interface Individual {
type: "individual";
birthDate: Date;
}
interface Corporation {
type: "corporation";
}
type PartyRoleInfo = { partyRole: "customer" } | {
partyRole: "other"
otherPartyRole: string
}
const validationResult = typia.validate<PartyWithRole>(individual);
if (!validationResult.success) {
throw validationResult;
}
Example result from above code:
{
success: false,
errors: [
{
path: '$input.partyRole',
expected: '"customer"',
value: 'other'
}
],
data: {
type: 'individual',
birthDate: 2025-06-10T10:43:59.087Z,
partyRole: 'other',
otherPartyRole: 'some-valid-string'
}
}
Oh yeah, for now, I am simply validating one section of my intersections as a workaround:
const validationResult = typia.validate<Party>(individual).success && typia.validate<PartyRoleInfo>(individual).success
Which seems to work fine so far, but obviously isn't great, since I won't be able to check for extraneous properties 😅
Just watned to plus one this. I have some code where I have to manually construct a validator for each side of the union otherwise typia fails.