Micha
Micha
Aarktype
Created by Micha on 2/5/2025 in #questions
Why is the generic expecting 3 options, although there is only one generic prop?
import { type, scope } from "arktype";

const types = scope({
queryValue: "null | string | number | bigint | boolean",
queryValueObject: {
"[string]": "queryValue",
},

"namedDocument<metadata extends queryValueObject = Record<string, never>>": { // namedDocument has only one generic "metadata"
"data?": "metadata",
},
}).export();

// this requires 3 options, but I would expect only 1 (metadata)
const namedDocument = types.namedDocument("object", "object", "object")
import { type, scope } from "arktype";

const types = scope({
queryValue: "null | string | number | bigint | boolean",
queryValueObject: {
"[string]": "queryValue",
},

"namedDocument<metadata extends queryValueObject = Record<string, never>>": { // namedDocument has only one generic "metadata"
"data?": "metadata",
},
}).export();

// this requires 3 options, but I would expect only 1 (metadata)
const namedDocument = types.namedDocument("object", "object", "object")
If I remove extends queryValueObject = Record<string, never> I only need 1 options. If I remove extends queryValueObject, it goes up to 4 options. And if I remove only = Record<string, never>, it also goes down to 1 required option.
5 replies
Aarktype
Created by Micha on 2/4/2025 in #questions
scope() how to bypass circular reference error?
I've implemented with Scope() successfully circular references, but somehow, I hit a limitation as this one still throws a circular reference error:
const types = scope({
queryValue: "namedDocument", // As soon as I add here namedDocument the error appears
queryValueObject: {
"[string]": "queryValue",
},

"namedDocument<metadata extends queryValueObject = Record<string, never>>": {
"data?": "metadata",
}
}).export();
const types = scope({
queryValue: "namedDocument", // As soon as I add here namedDocument the error appears
queryValueObject: {
"[string]": "queryValue",
},

"namedDocument<metadata extends queryValueObject = Record<string, never>>": {
"data?": "metadata",
}
}).export();
Error:
Type of property 'namedDocument' circularly references itself in mapped type '{ [k in "namedDocument<metadata extends queryValueObject>" as extractGenericName<k>]: GenericAst<conform<parseNextNameChar<skipWhitespace<extractParams<extractGenericParameters<k>>>, "", [], bootstrapAliases<...>>, array<...>>, { ...; }[k], "$", "$">; }'.ts(2615)
Type of property 'namedDocument' circularly references itself in mapped type '{ [k in "namedDocument<metadata extends queryValueObject>" as extractGenericName<k>]: GenericAst<conform<parseNextNameChar<skipWhitespace<extractParams<extractGenericParameters<k>>>, "", [], bootstrapAliases<...>>, array<...>>, { ...; }[k], "$", "$">; }'.ts(2615)
14 replies
Aarktype
Created by Micha on 2/4/2025 in #questions
How to integrate generics with extend that need to access a type in scope?
queryValueObject is currently not resolving, and I assume it's because type() is creating its own scope. The question is, how can I solve it then?
scope({
queryValue: [
"null | string | number | bigint | boolean | queryValueObject | queryValue[]",
uint8Array,
dateStub,
timeStub,
module,
],
queryValueObject: {
"[string]": "queryValue",
},
namedDocument: {
read: type("<metadata extends queryValueObject>", { // queryValueObject not resolving
coll: module,
name: "string",
ts: timeStub,
"data?": "metadata",
})
},
}).export();
scope({
queryValue: [
"null | string | number | bigint | boolean | queryValueObject | queryValue[]",
uint8Array,
dateStub,
timeStub,
module,
],
queryValueObject: {
"[string]": "queryValue",
},
namedDocument: {
read: type("<metadata extends queryValueObject>", { // queryValueObject not resolving
coll: module,
name: "string",
ts: timeStub,
"data?": "metadata",
})
},
}).export();
I also tried it by wrapping it into [], but this does also not work 🤔
read: ["<metadata extends queryValueObject>", {
coll: module,
name: "string",
ts: timeStub,
"data?": "metadata",
}]
read: ["<metadata extends queryValueObject>", {
coll: module,
name: "string",
ts: timeStub,
"data?": "metadata",
}]
15 replies
Aarktype
Created by Micha on 2/4/2025 in #questions
How to create the Typescript type from a generic?
https://arktype.io/docs/generics
const document = type({
id: "string",
coll: type.instanceOf(Module),
ts: TimeStub as type.cast<TimeStub>,
"ttl?": TimeStub as type.cast<TimeStub>,
});

const namedDocument = type("<t>",["t", "&",{
coll: type.instanceOf(Module),
name: "string",
ts: TimeStub as type.cast<TimeStub>,
"data?": "object",
}]);

const test = namedDocument(document) // This works as expected

type Document = typeof document;
type NamedDocument = typeof namedDocument;
const test: NamedDocument<Function> // This throws the error Type 'NamedDocument' is not generic.ts(2315)
const document = type({
id: "string",
coll: type.instanceOf(Module),
ts: TimeStub as type.cast<TimeStub>,
"ttl?": TimeStub as type.cast<TimeStub>,
});

const namedDocument = type("<t>",["t", "&",{
coll: type.instanceOf(Module),
name: "string",
ts: TimeStub as type.cast<TimeStub>,
"data?": "object",
}]);

const test = namedDocument(document) // This works as expected

type Document = typeof document;
type NamedDocument = typeof namedDocument;
const test: NamedDocument<Function> // This throws the error Type 'NamedDocument' is not generic.ts(2315)
7 replies
Aarktype
Created by Micha on 2/3/2025 in #questions
Is there a way to preserve jsdoc in arktype?
I have this piece of code:
/**
* Defines a {@link https://docs.fauna.com/fauna/current/learn/security/roles/#user-defined-role | user-defined role}. A role determines an authentication secret’s privileges, which control data access.
*
* Fauna stores user-defined roles as documents in the `Role` system collection. See {@link https://docs.fauna.com/fauna/current/reference/fql-api/auth/role/ | Role}.
*/
const role = type({
/**
* Assigns the role to tokens based on the {@link https://docs.fauna.com/fauna/current/learn/security/tokens/ | token’s} identity document. See for more information on {@link https://fauna.com/docs/reference/javascript#membership-roles | Membership definition}.
*/
"membership?": "string",
/**
* Allows one or more actions on a resource. See {@link https://docs.fauna.com/fauna/current/reference/fsl/role/#privileges-definition | Privileges definition}.
*/
"privileges?": "string",
});

export type Role = typeof role;
/**
* Defines a {@link https://docs.fauna.com/fauna/current/learn/security/roles/#user-defined-role | user-defined role}. A role determines an authentication secret’s privileges, which control data access.
*
* Fauna stores user-defined roles as documents in the `Role` system collection. See {@link https://docs.fauna.com/fauna/current/reference/fql-api/auth/role/ | Role}.
*/
const role = type({
/**
* Assigns the role to tokens based on the {@link https://docs.fauna.com/fauna/current/learn/security/tokens/ | token’s} identity document. See for more information on {@link https://fauna.com/docs/reference/javascript#membership-roles | Membership definition}.
*/
"membership?": "string",
/**
* Allows one or more actions on a resource. See {@link https://docs.fauna.com/fauna/current/reference/fsl/role/#privileges-definition | Privileges definition}.
*/
"privileges?": "string",
});

export type Role = typeof role;
At the moment the TS type Role don't have JsDoc as part of Intellisense. Also, role has only the overall jsdoc, but not for the key membership & privileges
2 replies
Aarktype
Created by Micha on 2/3/2025 in #questions
What is the arktype 2 syntax for inferring classes with a private constructor?
In Arktype 1.x I was writing:
import { type, Infer } from 'arktype';

const document = type({
"ttl?": ["instanceof", TimeStub] as Infer<TimeStub>,
})
import { type, Infer } from 'arktype';

const document = type({
"ttl?": ["instanceof", TimeStub] as Infer<TimeStub>,
})
But the Infer import is not more available in arktype 2, so I'm wondering how to achieve it now? Maybe the answer could be also added to the docs 🙂 https://arktype.io/docs/objects#instanceof
6 replies
Aarktype
Created by Micha on 2/3/2025 in #questions
How to create an array of type.instanceOf?
This doesn't work:
const documentReference = type.instanceOf(DocumentReference);

scope({
user: {
accounts: "documentReference[]",
}
}
const documentReference = type.instanceOf(DocumentReference);

scope({
user: {
accounts: "documentReference[]",
}
}
const documentReference = type.instanceOf(DocumentReference);

scope({
user: {
accounts: type.instanceOf(DocumentReference)[],
}
}
const documentReference = type.instanceOf(DocumentReference);

scope({
user: {
accounts: type.instanceOf(DocumentReference)[],
}
}
I only get it working without an array:
const documentReference = type.instanceOf(DocumentReference);

scope({
account: {
user: type.instanceOf(DocumentReference),
}
}
const documentReference = type.instanceOf(DocumentReference);

scope({
account: {
user: type.instanceOf(DocumentReference),
}
}
4 replies
Aarktype
Created by Micha on 3/17/2024 in #questions
How to specify a property of type function?
In Typescript I have defined it like this:
type User = {
accounts: accounts?: (() => Promise<Account>)[];
}
type User = {
accounts: accounts?: (() => Promise<Account>)[];
}
But how to achieve the same in Arktype? PS: Are there any soon plans to extend the Website with more examples? (e.g. the keyword page to explain how they need to be used e.g. Function ) I experience it as quite hard to find answers through the discord search.
11 replies
Aarktype
Created by Micha on 3/16/2024 in #questions
Why scope().compile().infer resolves to any?
I tried to follow the example here: https://arktype.io/docs/scopes Not sure if this is a bug or if I'm doing it wrong Stackblitz: https://stackblitz.com/edit/rzkceh-eodur9?file=demo.ts%3AL63,index.ts
import { Infer, scope } from "arktype"

export declare class TimeStub {
readonly isoString: string
/**
* @remarks constructor is private to enforce using factory functions
*/
private constructor()
/**
* Creates a new {@link TimeStub} from an ISO date string
* @param isoString - An ISO date string.
* @returns A new {@link TimeStub}
* @throws TypeError if a string is not provided, or RangeError if item
* is not a valid date
*/
static from(isoString: string): TimeStub
/**
* Creates a new {@link TimeStub} from a Javascript `Date`
* @param date - A Javascript `Date`
* @returns A new {@link TimeStub}
*/
static fromDate(date: Date): TimeStub
/**
* Get a copy of the `TimeStub` converted to a Javascript `Date`. Does not
* mutate the existing `TimeStub` value.
* @returns A `Date`
*/
toDate(): Date
/**
* Override default string conversion
* @returns the string representation of a `TimeStub`
*/
toString(): string
}

export const types = scope({
timeStub: ["instanceof", TimeStub] as Infer<TimeStub>,
account: "clientDocument&accountData",
clientDocument: {
"id?": "string",
"coll?": "string",
"ts?": ["instanceof", TimeStub] as Infer<TimeStub>,
"ttl?": ["instanceof", TimeStub] as Infer<TimeStub>
},
accountData: {
user: "user|timeStub",
provider: "provider",
providerUserId: "string"
},
user: {
name: "string",
"accounts?": "account[]"
},
provider: "'GitHub'|'Google'"
}).compile()

type Account = typeof types.account.infer
import { Infer, scope } from "arktype"

export declare class TimeStub {
readonly isoString: string
/**
* @remarks constructor is private to enforce using factory functions
*/
private constructor()
/**
* Creates a new {@link TimeStub} from an ISO date string
* @param isoString - An ISO date string.
* @returns A new {@link TimeStub}
* @throws TypeError if a string is not provided, or RangeError if item
* is not a valid date
*/
static from(isoString: string): TimeStub
/**
* Creates a new {@link TimeStub} from a Javascript `Date`
* @param date - A Javascript `Date`
* @returns A new {@link TimeStub}
*/
static fromDate(date: Date): TimeStub
/**
* Get a copy of the `TimeStub` converted to a Javascript `Date`. Does not
* mutate the existing `TimeStub` value.
* @returns A `Date`
*/
toDate(): Date
/**
* Override default string conversion
* @returns the string representation of a `TimeStub`
*/
toString(): string
}

export const types = scope({
timeStub: ["instanceof", TimeStub] as Infer<TimeStub>,
account: "clientDocument&accountData",
clientDocument: {
"id?": "string",
"coll?": "string",
"ts?": ["instanceof", TimeStub] as Infer<TimeStub>,
"ttl?": ["instanceof", TimeStub] as Infer<TimeStub>
},
accountData: {
user: "user|timeStub",
provider: "provider",
providerUserId: "string"
},
user: {
name: "string",
"accounts?": "account[]"
},
provider: "'GitHub'|'Google'"
}).compile()

type Account = typeof types.account.infer
15 replies
Aarktype
Created by Micha on 3/15/2024 in #questions
How to Union in scope()?
Union 1 will be resolved as I would expect to ts?: string | TimeStub | undefined;:
export const myType = type({
"id?": "string",
"coll?": "string",
"ts?": ["string", "|", ["instanceof", TimeStub] as Infer<TimeStub>]
})
export const myType = type({
"id?": "string",
"coll?": "string",
"ts?": ["string", "|", ["instanceof", TimeStub] as Infer<TimeStub>]
})
But Union 2
export const types = scope({
account: {
user: ["user", "|", ["instanceof", TimeStub] as Infer<TimeStub>],
provider: "provider",
providerUserId: "string"
},
user: {
name: "string",
"accounts?": "account[]"
},
provider: "'GitHub'|'Google'"
})
export const types = scope({
account: {
user: ["user", "|", ["instanceof", TimeStub] as Infer<TimeStub>],
provider: "provider",
providerUserId: "string"
},
user: {
name: "string",
"accounts?": "account[]"
},
provider: "'GitHub'|'Google'"
})
will be resolved to
account: { [k in keyof ({
user: any;
provider: "GitHub" | "Google";
providerUserId: string;
} & {} & {})]: ({
user: any;
provider: "GitHub" | "Google";
providerUserId: string;
} & {} & {})[k]; };
account: { [k in keyof ({
user: any;
provider: "GitHub" | "Google";
providerUserId: string;
} & {} & {})]: ({
user: any;
provider: "GitHub" | "Google";
providerUserId: string;
} & {} & {})[k]; };
although I would expect something like user: User | TimeStub If I'm trying to do the same with the base union syntax that I found "ts?": "string|['instanceof', TimeStub] as Infer<TimeStub>" I get a type error
Type '"string|['instanceof', TimeStub] as Infer<TimeStub>"' is not assignable to type '"string|string" | "string|number" | "string|bigint" | "string|boolean" | "string|symbol" | "string|undefined" | "string|object" | "string|null" | "string|Date" | "string|Error" | ... 25 more ... | "string|parsedDate"'.(2322)
demo.ts(44, 5): The expected type comes from property 'ts?' which is declared here on type '{ "id?": "string"; "coll?": "string"; "ts?": "string|string" | "string|number" | "string|bigint" | "string|boolean" | "string|symbol" | "string|undefined" | "string|object" | "string|null" | ... 27 more ... | "string|parsedDate"; }'
Type '"string|['instanceof', TimeStub] as Infer<TimeStub>"' is not assignable to type '"string|string" | "string|number" | "string|bigint" | "string|boolean" | "string|symbol" | "string|undefined" | "string|object" | "string|null" | "string|Date" | "string|Error" | ... 25 more ... | "string|parsedDate"'.(2322)
demo.ts(44, 5): The expected type comes from property 'ts?' which is declared here on type '{ "id?": "string"; "coll?": "string"; "ts?": "string|string" | "string|number" | "string|bigint" | "string|boolean" | "string|symbol" | "string|undefined" | "string|object" | "string|null" | ... 27 more ... | "string|parsedDate"; }'
https://stackblitz.com/edit/rzkceh-eodur9?file=demo.ts
6 replies
Aarktype
Created by Micha on 3/15/2024 in #questions
How to include an external class into an arktype type?
I tried
import { TimeStub } from 'fauna'; // class

const clientDocument = type({
'id?': 'string',
'coll?': 'string',
'ts?': TimeStub
});
import { TimeStub } from 'fauna'; // class

const clientDocument = type({
'id?': 'string',
'coll?': 'string',
'ts?': TimeStub
});
and
import { TimeStub } from 'fauna'; // class

const clientDocument = type({
'id?': 'string',
'coll?': 'string',
'ts?': ['instanceof', TimeStub]
});
import { TimeStub } from 'fauna'; // class

const clientDocument = type({
'id?': 'string',
'coll?': 'string',
'ts?': ['instanceof', TimeStub]
});
but both create a Type<never> for me. I'm using arktype 1.0.29-alpha
21 replies
Aarktype
Created by Micha on 3/1/2024 in #questions
Are you recommending to create first ArkType types and derive from their TS types or vice versa?
Are you recommending to create first ArkType types and derive from their TS types or vice versa?
2 replies