A
arktype•6d ago
snoww

Can Arktype create discriminated unions based on whether a key exists?

typescript
const MasterSkinItem = BaseItem.merge({
"+": "reject",
type: "'skin'",
masterItem: "true",

skin: "string",
short: "string",
weapon: WeaponUnion,

minPrice: "number.integer >=0",
stattrakAvailable: "boolean = false",
souvenirAvailable: "boolean = false",
qualities: type("1 | 2 | 3 | 4 |5").array().or(["null"]),
});

const SkinItem = BaseItem.merge({
"+": "reject",
type: "'skin'",
// "masterItem?": "false",
skin: "string",
short: "string",
weapon: WeaponUnion,

"weight?": "number",
souvenir: "boolean = false",
stattrak: "boolean = false",
quality: type("1 | 2 | 3 | 4 |5").optional(),
});
const Skinish = MasterSkinItem.or(SkinItem);
typescript
const MasterSkinItem = BaseItem.merge({
"+": "reject",
type: "'skin'",
masterItem: "true",

skin: "string",
short: "string",
weapon: WeaponUnion,

minPrice: "number.integer >=0",
stattrakAvailable: "boolean = false",
souvenirAvailable: "boolean = false",
qualities: type("1 | 2 | 3 | 4 |5").array().or(["null"]),
});

const SkinItem = BaseItem.merge({
"+": "reject",
type: "'skin'",
// "masterItem?": "false",
skin: "string",
short: "string",
weapon: WeaponUnion,

"weight?": "number",
souvenir: "boolean = false",
stattrak: "boolean = false",
quality: type("1 | 2 | 3 | 4 |5").optional(),
});
const Skinish = MasterSkinItem.or(SkinItem);
I have this union between two similar types, in the real world SkinItem never has masterItem as a key so this could be used to create a discriminated union, however i get ParseError if i omit "masterItem?": "false", in the definition for SkinItem. I think this is because ArkType is unable to discriminate based on key presence but I may also be missing something. I initially thought it was because ArkType accepts all keys but the error still happens even with key rejection on. My workaround isn't that annoying except for the fact that masterItem autocompletes on SkinItems.
1 Reply
ssalbdivad
ssalbdivad•5d ago
Hey thanks for submitting this! I took a look and found a bug with the way undeclared keys were reduced when extracting input, e.g. for ensuring that branches of a union don't overlap if they include morphs. That will be fixed in the next release (2.2), which will hopefully be published very soon! In the meantime, I'd recommend continuing to use your workaround, which was quite a smart solution! 🙌

Did you find this page helpful?