Andrew
Andrew
Aarktype
Created by Graff on 1/21/2025 in #questions
Recommended syntax for Higher Order Functions?
I've been running up against a similar issue where the correct return types are being erased when used in a type-factory style function. I'm not sure if there is a better approach to this, and maybe someone can do this without the ugly as any cast, but this can be achieved with some level of type safety using Modules and generics:
const uuid = type(
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
).brand("UID")
type uuid = typeof uuid.infer

const uuidModule = type.module({
"#baseSchema": type.object,
"withUUID< base extends baseSchema>": {
"...": "base",
uuid: uuid
}
})

const appendUUIDToSchema = <T extends object>(
schema: type.Any<T>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): type.Any<T & { uuid: uuid }> => uuidModule.withUUID(schema as any)

const baseWithUUID = appendUUIDToSchema(type({ abc: "string" }))

//This also generated the correct type:
const withUUID = uuidModule.withUUID({ abd: "string" })
const uuid = type(
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
).brand("UID")
type uuid = typeof uuid.infer

const uuidModule = type.module({
"#baseSchema": type.object,
"withUUID< base extends baseSchema>": {
"...": "base",
uuid: uuid
}
})

const appendUUIDToSchema = <T extends object>(
schema: type.Any<T>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
): type.Any<T & { uuid: uuid }> => uuidModule.withUUID(schema as any)

const baseWithUUID = appendUUIDToSchema(type({ abc: "string" }))

//This also generated the correct type:
const withUUID = uuidModule.withUUID({ abd: "string" })
3 replies