-
Notifications
You must be signed in to change notification settings - Fork 21
Open
Description
I'm trying to send better-result types from the backend into our frontend via TRPC, and writing the serializer is not as trivial as I would hope.
The isSerializedResult does not feel specific enough for me:
function isSerializedResult(obj: unknown): obj is SerializedResult<unknown, unknown> {
return (
obj !== null &&
typeof obj === "object" &&
"status" in obj &&
((obj.status === "ok" && "value" in obj) || (obj.status === "error" && "error" in obj))
);
}Sending status: 'ok' over our non-better-result API routes seems like it could easily happen, and we would then have a false positive deserialization.
Here's what my TRPC transformer looks like for now, only transforming from backend to frontend:
import { Err, Ok, Result } from 'better-result';
const trpcTransformer = {
input: {
deserialize: (obj: unknown): unknown => obj,
serialize: (obj: unknown): unknown => obj,
},
output: {
deserialize: (obj: unknown): unknown => {
// Result.serialize outputs { status: 'ok'|'error', value/error: ... }
if (
typeof obj === 'object' &&
obj !== null &&
'status' in obj &&
((obj as { status: string }).status === 'ok' ||
(obj as { status: string }).status === 'error')
) {
return Result.deserialize(obj);
}
return obj;
},
serialize: (obj: unknown): unknown => {
if (obj instanceof Ok || obj instanceof Err) {
return Result.serialize(obj as Result<unknown, unknown>);
}
return obj;
},
},
};I'd like to have something close to this:
import { Err, Ok, Result } from 'better-result';
const trpcTransformer = {
input: {
deserialize: (obj: unknown): unknown => obj,
serialize: (obj: unknown): unknown => obj,
},
output: {
deserialize: (obj: unknown): unknown => {
if (isSerializedResult(obj)) {
return Result.deserialize(obj);
}
return obj;
},
serialize: (obj: unknown): unknown => {
if (isResult(obj)) {
return Result.serialize(obj as Result<unknown, unknown>);
}
return obj;
},
},
};This leads to 2 ideas:
- Expose isSerializedResult and assertIsResult (or similar)
- Potentially make these checks more robust, with a more unique pattern than
'status' in value?- The simpler solution here is to convert the entire codebase to only send Result types from the backend, but that's not always an option
Maybe there's another alternative to get this right that I can't think of though!
Great library 👌
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels