jacksteamdev
jacksteamdev
Aarktype
Created by jacksteamdev on 11/9/2024 in #questions
Union Fallthrough?
I'm transforming some input using morphs like so:
const weightUnit = type({
value: 'number',
unit: toStringUnion(weightAliasList),
})
.pipe(({ value: fromValue, unit: fromUnit }) => {
const stdUnit = weightAliases[fromUnit as StandardWeightUnit];
const factor = standardUnitConversions.mg[stdUnit];
const toValue = Math.ceil(fromValue * factor);
return { value: toValue, unit: 'mg' };
})
.to({ value: 'number.integer', unit: '"mg"' });
const weightUnit = type({
value: 'number',
unit: toStringUnion(weightAliasList),
})
.pipe(({ value: fromValue, unit: fromUnit }) => {
const stdUnit = weightAliases[fromUnit as StandardWeightUnit];
const factor = standardUnitConversions.mg[stdUnit];
const toValue = Math.ceil(fromValue * factor);
return { value: toValue, unit: 'mg' };
})
.to({ value: 'number.integer', unit: '"mg"' });
And creating a union type like this, where otherUnit.unit is "string":
const normalizedUnit = weightUnit.or(volumeUnit).or(sizeUnit).or(otherUnit);
const normalizedUnit = weightUnit.or(volumeUnit).or(sizeUnit).or(otherUnit);
I expected otherUnit to catch non-matching values, but I'm getting this error:
ParseError: An unordered union of a type including a morph and a type with overlapping input is indeterminate:
Left: (In: { unit: string, value: number }) => Out<{ name: string, unit: "unit", value: number % 1 }>
Right: (In: { unit: "cup" | "cups" | "l" | "liter" | "liters" | "milliliter" | "milliliters" | "ml" | "tablespoon" | "tablespoons" | "tbsp" | "teaspoon" | "teaspoons" | "tsp", value: number }) => Out<{ unit: "ml", value: number % 1 }>
ParseError: An unordered union of a type including a morph and a type with overlapping input is indeterminate:
Left: (In: { unit: string, value: number }) => Out<{ name: string, unit: "unit", value: number % 1 }>
Right: (In: { unit: "cup" | "cups" | "l" | "liter" | "liters" | "milliliter" | "milliliters" | "ml" | "tablespoon" | "tablespoons" | "tbsp" | "teaspoon" | "teaspoons" | "tsp", value: number }) => Out<{ unit: "ml", value: number % 1 }>
Which makes sense if the union is unordered. Is there a way to make this union ordered? If not, is there a more fluent way to do this than wrapping it in a function?
16 replies
Aarktype
Created by jacksteamdev on 10/31/2023 in #questions
Unions with optional params?
Are unions with optional params supported in arktype? Example:
import { type, union } from "arktype"

const a = type({
direction: "'forward' | 'backward'",
"operator?": "'by'"
})

const b = type({
duration: "'s' | 'min' | 'h'",
"operator?": "'to'"
})

const c = union(a, b)

type TypeC = typeof c.infer

const test: TypeC = {
direction: "forward"
}

console.log("a", a(test))
console.log("c", c(test))

c.assert(test) // operator must be 'by' or 'to' (was undefined)
import { type, union } from "arktype"

const a = type({
direction: "'forward' | 'backward'",
"operator?": "'by'"
})

const b = type({
duration: "'s' | 'min' | 'h'",
"operator?": "'to'"
})

const c = union(a, b)

type TypeC = typeof c.infer

const test: TypeC = {
direction: "forward"
}

console.log("a", a(test))
console.log("c", c(test))

c.assert(test) // operator must be 'by' or 'to' (was undefined)
https://stackblitz.com/edit/fhz11y?file=type.ts
5 replies
Aarktype
Created by jacksteamdev on 8/8/2023 in #questions
How to validate that a value is an instance of a class
Is there a way (yet) to validate that a value is an instance of a class? I know this doesn't work, but maybe it'll convey the idea:
class SomeClass {}
const someType = type(SomeClass)
someType.allows("abc") // false
someType.allows(new SomeClass()) // true
class SomeClass {}
const someType = type(SomeClass)
someType.allows("abc") // false
someType.allows(new SomeClass()) // true
23 replies