-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
validate
with generics and arrays
#565
Comments
validate
with generics and arrays
That's correct. The code of the array validator breaks after the first invalid entry was found.
It does work with generics, but not out of the box automatically. In order to not have runtime overhead for each and every generic type argument, you have to explicitly tell Deepkit to embed the generic type into runtime. Otherwise the overhead would be too big and runtime code too slow. async function query<T>(sql: string, values: any[] = [], type?: ReceiveType<T>): Promise<T[]> {
type = resolveReceiveType(type);
const arrayType: TypeArray = { kind: ReflectionKind.array, type };
const rows = await database.query(sql, values);
const errors = validate<T[]>(rows, arrayType);
if (errors.length) {
throw Error("...");
}
return cast<T[]>(rows, undefined, undefined, undefined, arrayType);
} or async function query<T>(sql: string, values: any[] = [], type?: ReceiveType<T>): Promise<T[]> {
type = resolveReceiveType(type);
type ArrayType = InlineRuntimeType<typeof type>[];
const rows = await database.query(sql, values);
const errors = validate<ArrayType>(rows, arrayType);
if (errors.length) {
throw Error("...");
}
return cast<ArrayType>(rows, undefined, undefined, undefined, arrayType);
} or async function query<T>(sql: string, values: any[] = [], type?: ReceiveType<T>): Promise<T[]> {
type = resolveReceiveType(type);
type F = InlineRuntimeType<typeof type>;
const rows = await database.query(sql, values);
const errors = validate<F[]>(rows, arrayType);
if (errors.length) {
throw Error("...");
}
return cast<F[]>(rows, undefined, undefined, undefined, arrayType);
} |
Thank you for your quick and useful answer.
May I ask why ? To me, the error path being
This is clear thank you. However, to me, it seems to be some "noise" in the code you provided :
As a developer who have absolutely zero knowledge of how typing works inside, what I would prefer to do is something like that : async function query<T>(sql: string, values: any[] = []): Promise<T[]> {
type dynamicType = resolveRuntimeType<T>();
const rows = await database.query(sql, values);
const errors = validate<dynamicType[]>(rows, arrayType);
if (errors.length) {
throw Error("...");
}
return ...;
} I am not sure if a function can return a type or an interface like that, and I have no idea of the internal complexity of this, but as a developer, this would feel way more natural to do something straightforward like "get runtime type" then use it like any other type, not like an object. |
…ody as type reference This allows to have code like this more easily: ```typescript function mySerialize<T>(type?: ReceiveType<T>) { return cast<T>({}); } ``` It is still necessary to mark this function via ReceiveType though. this is the tradeoff we have in order to not embed too much JS code. ref #565
@NinjaKinshasa I agree. Having to deal with async function query<T>(sql: string, values: any[] = [], type?: ReceiveType<T>): Promise<T[]> {
const rows = await database.query(sql, values);
const errors = validate<T[]>(rows);
if (errors.length) {
throw Error("...");
}
return cast<T[]>(rows);
} A lot less boilerplate code. The only necessary marker is to use |
Instead of just first as previously deepkit#565 (comment)
Instead of just first as previously deepkit#565 (comment)
Instead of just first as previously #565 (comment)
Hello marcj,
Thank you for your work, I recently found deepkit and I'm trying to learn how to use it.
My interest is in the runtime validation provided by deepkit/type to ensure that my SQL queries are returning objects that matches with my typescript interfaces.
Unfortunately, I can't get it to work, because the
validate
function does not seem to handle correctly array type : it only validates the first item of the array.Also, the
validate
function does not work with generic types.Even if it is hacky and I don't like it, I can loop over the array and call validate on each item.
However, I do not see any workaround to deal with the generic type issue.
My initial idea was to do something like this :
But this does not work because
validate
always returns an empty array when using generic types.With this exemple, the cast returns an array of undefined values wether or not the interface is matching the objects.
I also tried to use
assert
but it works likevalidate
, which means that it doesn't detect the errors when using generics.What am I doing wrong here ? Thank you for you help
The text was updated successfully, but these errors were encountered: