How do I create an arktype equivalent to Record<string, CustomInterface[]>
with 2.0.0-beta.0?
#1058
-
Context: I'm type-validating the JSON output of MSBuild project evaluation commands. One of the nested types in the JSON object is I understand generics are W.I.P. and the tests for Record types are commented out. The solution, if there is one, will likely be esoteric. import { type } from "arktype"
// I know Record types can be created with only builtin types...
const record_string_string = type("Record<string, string>");
const record_string_stringArray = type("Record<string, string[]>");
const record_string_objectArray = type("Record<string, object[]>");
const record_string_MapArray = type("Record<string, Map[]>");
// ...but Records with custom-typed values don't work—the custom type cannot be resolved.
const arrayItem = type({
knownProp0: "string",
knownProp1: "string"
}).and("Record<string, string>");
type ArrayItem = typeof arrayItem.infer
const arrayItemArray = type(arrayItem.array())
type ArrayItemArray = typeof arrayItemArray.infer
// Record<string, (typeof arrayItem.infer)[]
// Argument of type '"Record<string, typeof arrayItemArray.infer>"' is not assignable to parameter of type '"'typeof' is unresolvable "'. ts(2345)
const record0 = type("Record<string, typeof arrayItemArray.infer>")
// Argument of type '"Record<string, arrayItemArray>"' is not assignable to parameter of type '"'arrayItemArray' is unresolvable "'. ts(2345)
const record1 = type("Record<string, arrayItemArray>");
// Argument of type '"Record<string, ArrayItemArray>"' is not assignable to parameter of type '"'ArrayItemArray' is unresolvable "'. ts(2345)
const record2 = type("Record<string, ArrayItemArray>");
// Type 'Type<{ [x: string]: string; knownProp0: string; knownProp1: string; }[], {}>' is not assignable to type '"'$' is unresolvable "'. ts(2322)
const record3 = type({ "[$: string]": arrayItemArray })
// Argument of type '"{ [x:string]: arrayItemArray }"' is not assignable to parameter of type '"'{' is unresolvable "'. ts(2345)
const record4 = type("{ [x:string]: arrayItemArray }") I've fiddled with |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Does this work for you? import { type, scope } from "arktype";
////// with type
const iItemMetadata = type({ key1: "string", key2: "string" }, "&", { "[string]": "string" });
/*
type IItemMetadata = {
[x: string]: string;
key1: string;
key2: string;
}
*/
type IItemMetadata = typeof iItemMetadata.infer;
const myRecord = type({ "[string]": iItemMetadata.array() });
/*
type MyRecord = {
[x: string]: {
[x: string]: string;
key1: string;
key2: string;
}[];
}
*/
type MyRecord = typeof myRecord.infer;
////// or with scope
const types = scope({
IItemMetadata: [
{ key1: "string", key2: "string" },
"&",
{ "[string]": "string", },
],
MyRecord: { "[string]": "IItemMetadata[]" },
}).export();
type IItemMetadata2 = typeof types.IItemMetadata.infer;
type MyRecord2 = typeof types.MyRecord.infer; There may be a cleaner/more idiomatic way to do it though? |
Beta Was this translation helpful? Give feedback.
-
I would recommend @maurice's answer with the slight adjustment that you don't need an intersection to specify an index signature alongside literal keys: const iItemMetadata = type({ key1: "string", key2: "string", "[string]": "string" });
const myRecord = type({ "[string]": iItemMetadata.array() }); Additionally, there will be an option to invoke builtin generics like ark.Record("string", iItemMetadata) Working on better docs for this now, sorry for the confusion in the meantime! |
Beta Was this translation helpful? Give feedback.
I would recommend @maurice's answer with the slight adjustment that you don't need an intersection to specify an index signature alongside literal keys:
Additionally, there will be an option to invoke builtin generics like
Record
directly on arbitrary definitions in the next release, so you will be able to use something like:Working on better docs for this now, sorry for the confusion in the meantime!