Skip to content

[Bug] Nested morphs not being applied correctly #1509

@vanillacode314

Description

@vanillacode314

Report a bug

🔎 Search Terms

nested morphs, default, pipe

🧩 Context

  • ArkType version: 2.1.22
  • TypeScript version (5.1+): 5.9.2
  • Other context you think may be relevant (JS flavor, OS, etc.):
    System:
    OS: Linux 6.16 Arch Linux
    Binaries:
    Node: 22.18.0 - /nix/store/vrqcpwq576gar2i430lj91v37b7k8jw2-nodejs-22.18.0/bin/node
    npm: 10.9.3 - /nix/store/vrqcpwq576gar2i430lj91v37b7k8jw2-nodejs-22.18.0/bin/npm
    bun: 1.2.13 - /nix/store/qpcadmqli2421b6whq5ffd0nlxncj856-bun-1.2.13/bin/bun

🧑‍💻 Repro

Playground Link: N/A (Playground unable to compile this snippet)

import { type Out, Type, type } from 'arktype'

class Option<T> {
  constructor(public value: T) {}
  static fromUndefinedOrNull<T>(value: T): Option<T> {
    return new Option(value)
  }
}

const asOption = <const def, T = type.infer<def>>(
  t: type.validate<def>,
): Type<(In: T | undefined | null) => Out<Option<T>>> => {
  const T = type(t).or('undefined | null') as unknown as Type<
    T | undefined | null
  >
  return T.pipe((value) => Option.fromUndefinedOrNull(value))
}

const asOptionWithDefault = <const def, T = type.infer<def>>(
  t: type.validate<def>,
): [Type<(In: T | undefined | null) => Out<Option<T>>>, '=', null] => {
  return asOption(t).default(null as any) as never
}

const x = type({
  a: asOptionWithDefault('number'),
})
const y = type({
  a: asOptionWithDefault(x),
})
console.log(y.assert({ a: {} }))
// prints:
// { a: Option { value: { a: null, } } }
// expected:
// { a: Option { value: { a: Option { ... } } } }

export { asOption, asOptionWithDefault }

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status

To do

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions