Struggling to define a simple recursive type #1137
-
I am trying to define a recursive type, which can be type Value = boolean | number | string | { [k: string]: Value} | Value[]; This does not compile with const $ = scope({
primitive: 'boolean | number | string',
record: {
'[string]': 'value'
},
value: 'primitive | record | value[]'
}).export(); Full code: import { ArkErrors, scope } from 'arktype';
type Value = boolean | number | string | { [k: string]: Value} | Value[];
const $ = scope({
primitive: 'boolean | number | string',
record: {
'[string]': 'value'
},
value: 'primitive | record | value[]'
}).export();
const schema = $.value;
async function main() {
const value = [ '42 '];
// const t: typeof schema.infer = [ '42' ]; // Fails to compile if value[] is removed above
const result = schema(value);
if (result instanceof ArkErrors) {
console.error('FAIL:', result.summary);
} else {
console.log('PASS', result);
}
}
main().catch((e: unknown) => {
console.trace(e);
}); Observation: if I remove Anyway, please help me to find where I can read on how to define such a recursive type? An example of how to write a schema for JSON would be really nifty. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 14 replies
-
One note would be you can reuse your type Value = boolean | number | string | { [k: string]: Value } | Value[]
const $ = scope({
primitive: "boolean | number | string",
record: {
"[string]": "value"
},
value: "primitive | record | value[]" as type.cast<Value>
}).export() Unfortunately, there's still a problem where we try to extract the output type and get stuck in a loop. Perhaps related to some changes I made recently handling array intersections. Created this issue to track it: |
Beta Was this translation helpful? Give feedback.
Here's one potential workaround you can use to tell ArkType not to recurse into your JSON array type, although it could interface with e.g. extracting morphs out of some other types because of how broad
Value[]
is.If you were to also brand
Value
likeValue[] & {[mySymbol]: "jsonArray"}
, I think that would be safe.