A
arktype•3mo ago
dibbo

Indexed Access Types

Hello, is it possible to recreate the SizeValues type below in arktype?
const sizes = [
{ label: "Big", value: "100kg" },
{ label: "Medium", value: "50kg" },
{ label: "Small", value: "10kg" },
] as const;

type SizeValues = typeof sizes[number]['value'][]
const sizes = [
{ label: "Big", value: "100kg" },
{ label: "Medium", value: "50kg" },
{ label: "Small", value: "10kg" },
] as const;

type SizeValues = typeof sizes[number]['value'][]
5 Replies
PIat
PIat•3mo ago
One way to do it:
const sizes = type([
'===',
[
{
label: 'Big',
value: '100kg',
},
{ label: 'Medium', value: '50kg' },
{ label: 'Small', value: '10kg' },
],
])

type SizeValue = inferAmbient<typeof sizes>[number]['value']
const sizes = type([
'===',
[
{
label: 'Big',
value: '100kg',
},
{ label: 'Medium', value: '50kg' },
{ label: 'Small', value: '10kg' },
],
])

type SizeValue = inferAmbient<typeof sizes>[number]['value']
But I wouldn't see the use case for this particular type... What are you planning to do with it?
frolic
frolic•3mo ago
GitHub
Index access expressions · Issue #831 · arktypeio/arktype
Would allow expressions like the following: const types = scope({ base: { foo: "true", bar: "false", }, // 1:1 with TS foo: "base['foo']", // Allow more conven...
dibbo
dibboOP•3mo ago
Thank you! Good question... I've been looking at this for so long I can't remember 😂 Let me give a more detailed example: I'm trying to create a type to be used to validate the payload in a search request. I've landed on this as the implementation
const status = ["Available", "Unavailable", "Sold"] as const;
const size = [
{ label: "Big", value: "100kg" },
{ label: "Small", value: "10kg" },
] as const;

const searchPayload = type({
"page?": "number",
"sort?": "string",
filters: {
"status?": type(["===", ...status]).array(),
"size?": type(["===", ...size.map((s) => s.value)]).array(),
},
});

type SearchPayload = typeof searchPayload.infer;
// Evaluates to the type I want
// type SearchPayload = {
// filters: {
// status?: ("Available" | "Unavailable" | "Sold")[];
// size?: ("100kg" | "10kg")[];
// };
// page?: number;
// sort?: string;
// }
const status = ["Available", "Unavailable", "Sold"] as const;
const size = [
{ label: "Big", value: "100kg" },
{ label: "Small", value: "10kg" },
] as const;

const searchPayload = type({
"page?": "number",
"sort?": "string",
filters: {
"status?": type(["===", ...status]).array(),
"size?": type(["===", ...size.map((s) => s.value)]).array(),
},
});

type SearchPayload = typeof searchPayload.infer;
// Evaluates to the type I want
// type SearchPayload = {
// filters: {
// status?: ("Available" | "Unavailable" | "Sold")[];
// size?: ("100kg" | "10kg")[];
// };
// page?: number;
// sort?: string;
// }
I was wondering if there was a cleaner/preferred way to pick out the value prop from the size array with arktype, rather than creating a new array via the map.
PIat
PIat•3mo ago
It seems clean to me. You have the config in a centralized object. Other ways would probably include splitting it up into multiple smaller types and then connecting them If you're going to reuse the status and sizes in different places, you could create a type from them and then nest it somewhere
const status = ["Available", "Unavailable", "Sold"] as const;
const size = [
{ label: "Big", value: "100kg" },
{ label: "Small", value: "10kg" },
] as const;

const statusType = type(["===", ...status]).array()

const sizeType = type(["===", ...size.map((s) => s.value)]).array()

const searchPayload = type({
"page?": "number",
"sort?": "string",
filters: {
"status?": statusType,
"size?": sizeType,
},
});
const status = ["Available", "Unavailable", "Sold"] as const;
const size = [
{ label: "Big", value: "100kg" },
{ label: "Small", value: "10kg" },
] as const;

const statusType = type(["===", ...status]).array()

const sizeType = type(["===", ...size.map((s) => s.value)]).array()

const searchPayload = type({
"page?": "number",
"sort?": "string",
filters: {
"status?": statusType,
"size?": sizeType,
},
});
dibbo
dibboOP•3mo ago
Nice, thank you for the help!
Want results from more Discord servers?
Add your server