Arktype does not work in Expo, when Disjoint.withPrefixKey is called internally
Report a bug
The same issue that was reported in issue #1027 and fixed in arktype version 2.1.4 for Disjoint.invert is also present in Disjoint.withPrefixKey (and not yet fixed, as of version 2.2.3). Hermes does not preserve Array subclasses through Array.prototype.map.
Search Terms
Expo, React Native, Hermes
Context
Arktype 2.2.3 Typescript 7.0.2 Expo SDK 57 React Native 0.86.2 Hermes 0.16
Repro
The issue can be reproduced with any union of two object literals whose branches are disjoint at a key. For example:
import { type } from "arktype"
// TypeError: undefined is not a function
const result = type({
results: "Record<string, unknown>[][]",
success: "true"
}).or({
errors: "string[]",
results: "Record<string, unknown>[][]",
success: "false"
})On Expo SDK 57 / React Native 0.86.2 / Hermes 0.16, this throws TypeError: undefined is not a function at the .or(...) call at runtime.
Suggested fix
We can use a similar fix/workaround like @dolgim suggested in #1027. I patched arktype locally with the following, and can confirm that it works:
withPrefixKey(key: PropertyKey, kind: Prop.Kind): Disjoint {
const result = this.map(entry => ({
...entry,
path: [key, ...entry.path],
optional: entry.optional || kind === "optional"
}))
// Workaround for Hermes
if (!(result instanceof Disjoint)) return new Disjoint(...result)
return result
}However, we might need a solution that avoids any similar issues. E.g. we could make Disjoint no longer extend Array.
Source: arktypeio/arktype