Dimava
Dimava
Aarktype
Created by Dimava on 10/29/2024 in #questions
Compiling scope to interfaces
I have a huge scope and I want to extract 10+ interfaces from it, preferably in a way that would compile plainly to d.ts And then remake the scope with using those interfaces
const S = scope({
foo: { a: number }
bar: { foo: foo }
})
export interface Foo = ???
export interface Bar = ??? // should be { foo: Foo }
const S = scope({
foo: { a: number }
bar: { foo: foo }
})
export interface Foo = ???
export interface Bar = ??? // should be { foo: Foo }
What the best way for that
38 replies
Aarktype
Created by Dimava on 10/15/2024 in #questions
Generic modules, Enums and AnyOf
There are at least 3 threads asking for OneOf I suggest making a Enum generic (called OneOf maybe) that works as following: - it accepts an object definition O - it has a root type which allows any of the property values O[keyof O] - it is a module with all property types as its values, Module<{ [K in keyof O]: Type<O[K]> }> Then it's easy to use it for both cases of an enum with constant values
scope({
_e: { One: 'one', Two: 'two', Three: 'three' }.
oneTwoThree: 'Enum<_e>',
list: [{ num: 'oneTwoThree' },'[]'],
first: { num: 'oneTwoThree.one' },
second: { num: 'oneTwoThree.tow' }, // type error, this typo be easily missed if it was `"tow"`
})
scope({
_e: { One: 'one', Two: 'two', Three: 'three' }.
oneTwoThree: 'Enum<_e>',
list: [{ num: 'oneTwoThree' },'[]'],
first: { num: 'oneTwoThree.one' },
second: { num: 'oneTwoThree.tow' }, // type error, this typo be easily missed if it was `"tow"`
})
and when you just want to intersect a bunch of types
todo
todo
8 replies
Aarktype
Created by Dimava on 10/3/2024 in #questions
Using `atLeastLength` on morphed array
How do I do
it("can use atLeastLength on piped array", () => {
const SortedArray = type("string[]").pipe(s => s.sort()).to('string[]')
const NonEmptySortedArray = SortedArray.atLeastLength(1)
attest(NonEmptySortedArray(['1', '2', '3'])).snap()
})
it("can use atLeastLength on piped array", () => {
const SortedArray = type("string[]").pipe(s => s.sort()).to('string[]')
const NonEmptySortedArray = SortedArray.atLeastLength(1)
attest(NonEmptySortedArray(['1', '2', '3'])).snap()
})
?
9 replies
Aarktype
Created by Dimava on 10/2/2024 in #questions
Pipe chains don't work in rc13
I'm trying to make a logging wrapper to help me debug my Types but pipes don't seem to chain
function logWrapper<T extends type.Any>(T: T): T {
return (T.in as type.Any).pipe(
(v: any) => { console.log({ before: v }); return v },
T,
(v: any) => { console.log({ after: v }); return v },
) as any
}

const result = logWrapper(type('string.numeric.parse'))('1')
console.log({ result })
// logs { before: "1" } { after: "1" } { result: 1 }
function logWrapper<T extends type.Any>(T: T): T {
return (T.in as type.Any).pipe(
(v: any) => { console.log({ before: v }); return v },
T,
(v: any) => { console.log({ after: v }); return v },
) as any
}

const result = logWrapper(type('string.numeric.parse'))('1')
console.log({ result })
// logs { before: "1" } { after: "1" } { result: 1 }
39 replies
Aarktype
Created by Dimava on 10/1/2024 in #questions
How to check if a function is Type instance?
title
3 replies
Aarktype
Created by Dimava on 9/30/2024 in #questions
Extenting Type interface
I want to make a custom function type({}).migrate() and add it to BaseType prototype How do I do it properly?
3 replies
Aarktype
Created by Dimava on 9/30/2024 in #questions
Morph on failure
I have a type
const T = type({ id: "string>0", label: "string>0" })
const T = type({ id: "string>0", label: "string>0" })
and objects of type { id: string>0, label?: string>=0 } and want to create a type that will try to morph with (o: { id: string>0, label?: string>=0 }) => { o.label ||= o.id } only on failure, and then try to revalidate with the same validator What's the best way to do that?
5 replies
Aarktype
Created by Dimava on 9/23/2024 in #questions
`scope.validate` for a scope with imports
The usage of type.validate with custom existing scopes is straightforward - just use type.validate<def, scope.t> However, how do I validate a new scope definition with existing imports/exports?
import { scope, type } from 'arktype'

const baseScope = scope({
'id': 'string'
})
type $ = typeof baseScope.t

function myType<const def>(def: type.validate<def, $>): type.infer<def, $> {
return baseScope.type(def)
}
myType({ x: 'id' })

function myScopeWithExport<const def>(def: scope.validate<def>): scope.infer<def> {
return scope({
...baseScope.export(),
...def
} as any) as any
}
myScopeWithExport({ x: 'id' })

function myScopeWithImport<const def>(def: scope.validate<def>): scope.infer<def> {
return scope({
...baseScope.import(),
...def
} as any) as any
}
myScopeWithImport({ x: 'id' })
import { scope, type } from 'arktype'

const baseScope = scope({
'id': 'string'
})
type $ = typeof baseScope.t

function myType<const def>(def: type.validate<def, $>): type.infer<def, $> {
return baseScope.type(def)
}
myType({ x: 'id' })

function myScopeWithExport<const def>(def: scope.validate<def>): scope.infer<def> {
return scope({
...baseScope.export(),
...def
} as any) as any
}
myScopeWithExport({ x: 'id' })

function myScopeWithImport<const def>(def: scope.validate<def>): scope.infer<def> {
return scope({
...baseScope.import(),
...def
} as any) as any
}
myScopeWithImport({ x: 'id' })
3 replies
Aarktype
Created by Dimava on 9/16/2024 in #questions
Generic with Narrow/Morph
I want to make something like
type UniqueArray<T, K extends keyof T>


export const UniqueArray = brandsScope.type.generic('T', 'K extends keyof T', ['T[]', ':', (v, ctx) => {
let vals = new Set(v.map(e => e[erm what]))
if (vals.length !== v.length) return ctx.mustBe(`array with uniue $K`)
return true
}])
type UniqueArray<T, K extends keyof T>


export const UniqueArray = brandsScope.type.generic('T', 'K extends keyof T', ['T[]', ':', (v, ctx) => {
let vals = new Set(v.map(e => e[erm what]))
if (vals.length !== v.length) return ctx.mustBe(`array with uniue $K`)
return true
}])
Please help me to make it work
4 replies
Aarktype
Created by Dimava on 9/12/2024 in #questions
`string.integer.parsed` with limits
I need a simple port number, 1 < integer < 9999 Hovewer, I want to parse it from env string so I need string.integer.parse How do I make the limited parsed integer?
37 replies
Aarktype
Created by Dimava on 6/18/2024 in #questions
Type Magic: validation on type property
How to validate defs in object type properties?
export type validateSchema<
def,
schema,
> = {
[K in keyof schema]:
K extends keyof def
? validateTypeRoot<def[K]>
: validateTypeRoot<unknown>
}

function test<const def>(
def: validateSchema<def, { a: 1 }>,
) { }

test({
a: 'str',
})
export type validateSchema<
def,
schema,
> = {
[K in keyof schema]:
K extends keyof def
? validateTypeRoot<def[K]>
: validateTypeRoot<unknown>
}

function test<const def>(
def: validateSchema<def, { a: 1 }>,
) { }

test({
a: 'str',
})
I did that three days ago but I forgot how
31 replies
Aarktype
Created by Dimava on 6/15/2024 in #questions
Usage for HTTP validation
I'm looking to use Arktype as a Request/Response validator This comes with the following requirements: - Request body should be validated with deep reject unknownKeys so invalid requests are immediately 422 - Response should be validated with deep delete unknownKeys so local information can't passthrough - Response input should be cloned rather then inline-morphed (including key deletion) so you can pass in input objects as-is
let User = type({ name: string, meta: { bio: 'string' } })
let CreateUser = type([ User, '&', { password: string, meta: { age: 'number' } } ])
let UserModel = type([ CreateUser, '&', { meta: { isAdult: 'boolean' } } ])

let oneUser: UserModel;
function addUser(user: CreateUser) {
// should throw on inputs with extra keys on user and on user.meta
let newUser = AT_asHttpIn(CreateUser).assert(user)
newUser.meta.isAdult = newUser.meta.age >= 18
oneUser = AT_strict(UserModel).assert(newUser)
}
function getUser() {
// should remove password and age
// should not remove them on actual data
return AT_asHttpOut(User).assert(oneUser)
}
let User = type({ name: string, meta: { bio: 'string' } })
let CreateUser = type([ User, '&', { password: string, meta: { age: 'number' } } ])
let UserModel = type([ CreateUser, '&', { meta: { isAdult: 'boolean' } } ])

let oneUser: UserModel;
function addUser(user: CreateUser) {
// should throw on inputs with extra keys on user and on user.meta
let newUser = AT_asHttpIn(CreateUser).assert(user)
newUser.meta.isAdult = newUser.meta.age >= 18
oneUser = AT_strict(UserModel).assert(newUser)
}
function getUser() {
// should remove password and age
// should not remove them on actual data
return AT_asHttpOut(User).assert(oneUser)
}
Please list recommended AT APIs for this Please link the related undone issues is any
64 replies
Aarktype
Created by Dimava on 8/18/2023 in #questions
Context-sensitive validation / validation with parameters
interface Thing {
bars: string[];
foo: { baz: { bar: string }[]; }[];
}
interface Thing {
bars: string[];
foo: { baz: { bar: string }[]; }[];
}
What is the best/easiest way to write a validator which ensures that all bars are present in bars?
41 replies
Aarktype
Created by Dimava on 5/15/2023 in #questions
Custom type-making functions
I want to make a chainable that can create types the same way type does How do I implement that?
thing // Thing<never, never>
.input('number%1>0') // Thing<number, never>
.output({ items: 'string[]' }) // Thing<number, {items: string[]}>
thing // Thing<never, never>
.input('number%1>0') // Thing<number, never>
.output({ items: 'string[]' }) // Thing<number, {items: string[]}>
2 replies
Aarktype
Created by Dimava on 5/4/2023 in #questions
How to access current scope types with `type()` / `morph()` / `narrow()` / `arrayOf()` inside scope?
How to access current scope types with type() / morph() / narrow() / arrayOf() inside scope?
const $ = scope({
blah: "1 < number < 10",
blahArray: () => $.type("blah[]")
})

const types = $.compile()
const $ = scope({
blah: "1 < number < 10",
blahArray: () => $.type("blah[]")
})

const types = $.compile()
2 replies