A
arktype3d ago
Tony

Optional required pairs?

I have a type that has all optional properties. However I want to want to make 2 options a pair - if one exists, the other is required. An example:
const props = type({
'propA?': 'string',
'propB?': 'string',
'propC?': 'string'
});

// valid
props({ propA: 'test' });

// not valid - propB requires propC as well, and vice versa
props({ propB: 'test' });
props({ propC: 'test' });

// valid - both provided
props({ propB: 'test', propC: 'test' });
const props = type({
'propA?': 'string',
'propB?': 'string',
'propC?': 'string'
});

// valid
props({ propA: 'test' });

// not valid - propB requires propC as well, and vice versa
props({ propB: 'test' });
props({ propC: 'test' });

// valid - both provided
props({ propB: 'test', propC: 'test' });
Is this doable? I'm using Arktype for validating incoming JSON in a server, so the use case for it is changing passwords, if you want to change your password you need to provide the current password as well, and maybe the new password a second time to confirm it
2 Replies
TizzySaurus
TizzySaurus3d ago
One way would be to use .narrow(), which has the added benefit of being able to specify custom errors:
const props = type({ ... }).narrow((obj, ctx) =>
"propB" in obj === "propC" in obj
? true
: ctx.mustBe({
expected:
"an object that either includes both or neither of 'propB' and 'propC'",
})
);
const props = type({ ... }).narrow((obj, ctx) =>
"propB" in obj === "propC" in obj
? true
: ctx.mustBe({
expected:
"an object that either includes both or neither of 'propB' and 'propC'",
})
);
ssalbdivad
ssalbdivad3d ago
@Tony You could use something like this:
type({
"propA?": "string",
"propB?": "never",
"propC?": "never"
}).or({
"propA?": "string",
propB: "string",
propC: "string"
})
type({
"propA?": "string",
"propB?": "never",
"propC?": "never"
}).or({
"propA?": "string",
propB: "string",
propC: "string"
})
Want results from more Discord servers?
Add your server