Report a bug
Related: #1596, #1468
Arktype is dropping previous narrowing functions after pipe.
Specifically, having multiple pipe > narrow operations in an intersection schema drops narrow condition of the member schemas with pipe > narrow and only run the narrowing condition of the intersection schema
(A_pipe_narrow | B_narrow) & C_pipe_narrow
A narrow will not work
B narrow will still work
C narrow will still work
(A_narrow | B_narrow) & C_pipe_narrow
A narrow will still work
B narrow will still work
C narrow will still work
(A_pipe_narrow | B_narrow) & C_pipe
A narrow will still work
B narrow will still work
(A_pipe_narrow | B_narrow) & C_narrow
A narrow will still work
B narrow will still work
C narrow will still work
🔎 Search Terms
🧩 Context
- ArkType version: 2.2.0
- TypeScript version (5.1+): 5.9.3
- Other context you think may be relevant (JS flavor, OS, etc.):
🧑💻 Repro
Playground Link: https://arktype.io/playground
import { type } from "arktype"
const PipedItem = type("string.numeric & string.numeric.parse").narrow(
(_data, ctx) => {
ctx.reject("always reject")
return true
}
)
const PipedItem2 = type("string").narrow((_data, ctx) => {
ctx.reject("always reject")
return true
})
const Variant = type({
kind: '"a"',
value: PipedItem
})
//Dropping this variant also fixes the issue
.or({
kind: '"b"',
value: PipedItem2
})
const Meta = type({
// If you have this the narrowing breaks
code: type("string.numeric.parse")
})
//Dropping this narrow also fixes the issue
.narrow((data, ctx) => {
return true
})
const Thing = Variant.and(Meta)
// This behaves the same as Variant.and(Meta) by forcing data to be validated with Variant and triggers Variant narrow.
// We do trigger Variant validation twice
const ThingWorkaround = Variant.and(Meta).narrow((data, ctx) => {
const baseResult = Variant(data)
if (baseResult instanceof type.errors) ctx.reject(baseResult.summary)
return true
})
// This must reject and does
const goodThing = {
kind: "b",
code: "1",
value: ""
}
// This must reject but doesnt
const badThing = {
kind: "a",
code: "1",
value: "1"
}
const out = Thing(badThing)
Workaround pnpm patch:
Im not aware of how this will affect performance, but it seems to fix this and #1596 due to rawIn stripping narrow functions of child branches.
diff --git a/out/roots/union.js b/out/roots/union.js
index fbe3ccb58ef55e6922bd1ed79e8ab8e485f9a0c2..cf6482d23195bdeee743cbfbe565d06fe70ad394 100644
--- a/out/roots/union.js
+++ b/out/roots/union.js
@@ -31,7 +31,7 @@ const implementation = implementNode({
const matchingMorph = branches[matchingMorphIndex];
branches[matchingMorphIndex] = ctx.$.node("morph", {
...matchingMorph.inner,
- in: matchingMorph.rawIn.rawOr(node.rawIn)
+ in: matchingMorph.inner.in.rawOr(node.inner.in)
});
}
}
Report a bug
Related: #1596, #1468
Arktype is dropping previous narrowing functions after pipe.
Specifically, having multiple pipe > narrow operations in an intersection schema drops narrow condition of the member schemas with pipe > narrow and only run the narrowing condition of the intersection schema
🔎 Search Terms
🧩 Context
🧑💻 Repro
Playground Link: https://arktype.io/playground
Workaround pnpm patch:
Im not aware of how this will affect performance, but it seems to fix this and #1596 due to rawIn stripping narrow functions of child branches.