Piping types no longer works

import { type } from "arktype";

const Letters = type("'a'|'b'|'c'");
const Letter = type("string").pipe((s) => Letters(s));

console.log(Letter.assert("d"));
import { type } from "arktype";

const Letters = type("'a'|'b'|'c'");
const Letter = type("string").pipe((s) => Letters(s));

console.log(Letter.assert("d"));
In previous version of ArkType (have tested 2.0.0-rc.7 and below), this worked as intended where it'll throw an error since d does not match a/b/c. In ArkType >= 2.0.0-rc.13 this now doesn't throw an error and instead outputs d
6 Replies
SynthLuvr
SynthLuvrOP2mo ago
import { type } from "arktype";

const Letters = type("'a'|'b'|'c'");
const Letter = type("string").pipe((s, ctx) => {
const result = Letters(s);
return result instanceof type.errors ? ctx.error(result) : result;
});

console.log(Letter.assert("d"));
import { type } from "arktype";

const Letters = type("'a'|'b'|'c'");
const Letter = type("string").pipe((s, ctx) => {
const result = Letters(s);
return result instanceof type.errors ? ctx.error(result) : result;
});

console.log(Letter.assert("d"));
Produces:
description: node => `valid according to ${node.predicate.name || "an anonymous predicate"}`
^

TypeError: Cannot read properties of undefined (reading 'name')
description: node => `valid according to ${node.predicate.name || "an anonymous predicate"}`
^

TypeError: Cannot read properties of undefined (reading 'name')
ctx.error(result.summary) works, but then duplicates the error AggregateError: must be must be "a", "b" or "c" (was "d") (was "d")
import { type } from "arktype";

const Letters = type("'a'|'b'|'c'");
const Letter = type("string").pipe((s) => {
const result = Letters(s);
return result instanceof type.errors ? result.at(0)! : result;
});

console.log(Letter.assert("d"));
import { type } from "arktype";

const Letters = type("'a'|'b'|'c'");
const Letter = type("string").pipe((s) => {
const result = Letters(s);
return result instanceof type.errors ? result.at(0)! : result;
});

console.log(Letter.assert("d"));
This seems to produce the same behavior I'm accustomed to:
AggregateError: must be "a", "b" or "c" (was "d")
AggregateError: must be "a", "b" or "c" (was "d")
hmm, not quite Got it
const Letters = type("'a'|'b'|'c'");
const Letter = type("string").pipe((s, ctx) => {
const result = Letters(s);
return result instanceof type.errors
? ctx.error(result.at(0)!.expected!)
: result;
});
const Letters = type("'a'|'b'|'c'");
const Letter = type("string").pipe((s, ctx) => {
const result = Letters(s);
return result instanceof type.errors
? ctx.error(result.at(0)!.expected!)
: result;
});
ssalbdivad
ssalbdivad2mo ago
This will work better if you just .to or .pipe to Letters directly rather than creating your own wrapper function that passes s. Still, this should continue to work and I will fix it in the next release. But if you pipe to a type directly, you get introspectable output and optimizations in addition to it being more concise
SynthLuvr
SynthLuvrOP2mo ago
Ok that works. I think it was broken in the past which is why I had to wrap it, but seems to be working now
ssalbdivad
ssalbdivad2mo ago
The original case is fixed in 2.0.0-rc.14, though best continue to use .to directly
Dimava
Dimava2mo ago
What's the difference between pipe and to? I'll add to JSDoc pr
ssalbdivad
ssalbdivad2mo ago
To accepts a single type definition so is mainly a convenience so that if you're defining an output, you don't have to rewrap in type. It's also only available if your type is already a morph.
Want results from more Discord servers?
Add your server