import { type Out, Type, type } from 'arktype'
// import { Option } from 'ts-result-option'
class Option<T> {
constructor(public value: T) {}
isNone(): boolean {
return false
}
isSome(): boolean {
return true
}
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, ctx) => Option.fromUndefinedOrNull(value))
}
const asOptionWithDefault = <const def, T = type.infer<def>>(
t: type.validate<def>,
): Type<(In: [T | undefined | null, '=', null]) => Out<Option<T>>> => {
return asOption(t).default(null)
}
const x = type({
a: asOptionWithDefault('number'),
})
const y = type({
a: asOptionWithDefault(x),
})
console.log(y.assert({ a: {} }))
// prints:
// {
// a: Option {
// value: {
// a: null,
// },
// isNone: [Function: isNone],
// isSome: [Function: isSome],
// },
// }
// expected:
// {
// a: Option {
// value: {
// a: Option { ... },
// },
// isNone: [Function: isNone],
// isSome: [Function: isSome],
// },
// }
export { asOption, asOptionWithDefault }
import { type Out, Type, type } from 'arktype'
// import { Option } from 'ts-result-option'
class Option<T> {
constructor(public value: T) {}
isNone(): boolean {
return false
}
isSome(): boolean {
return true
}
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, ctx) => Option.fromUndefinedOrNull(value))
}
const asOptionWithDefault = <const def, T = type.infer<def>>(
t: type.validate<def>,
): Type<(In: [T | undefined | null, '=', null]) => Out<Option<T>>> => {
return asOption(t).default(null)
}
const x = type({
a: asOptionWithDefault('number'),
})
const y = type({
a: asOptionWithDefault(x),
})
console.log(y.assert({ a: {} }))
// prints:
// {
// a: Option {
// value: {
// a: null,
// },
// isNone: [Function: isNone],
// isSome: [Function: isSome],
// },
// }
// expected:
// {
// a: Option {
// value: {
// a: Option { ... },
// },
// isNone: [Function: isNone],
// isSome: [Function: isSome],
// },
// }
export { asOption, asOptionWithDefault }