question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Callback on function arguments throws error

See original GitHub issue

I’ve started using this package to automatically infer types for Typescript declarations and to ensure object schemas, however I’ve came across some issues when it comes to having callbacks on functions.

When declarating a function like this:

function processAndCallback(num, string, callback) {
    // Process data...
    callback(err, "some string", 0)
}

And using a Zod Schema like:

const schema = z.function()
  .args(
    z.number(),
    z.string(),	
    z.function()
        .args(
            z.instanceof(Error),
            z.string({
                invalid_type_error: "Paramether must be a string value",
            }),
            z.number({
                invalid_type_error: "Paramether must be a numeric value",
            })
        )
        .returns(z.void())
        .implement((err: Error, address: string, family: number) => {
            err;
            address;
            family;

            return;
        })
    )
    .returns(z.void())
    .implement((err, options, callback) => {
        err;
        options;
        callback;

        return;
    })

The following error is thrown:

Argument of type '[ZodNumber, ZodString, (err: Error, address: string, family: number) => void]' is not assignable to parameter of type '[] | [ZodTypeAny, ...ZodTypeAny[]]'.
  Type '[ZodNumber, ZodString, (err: Error, address: string, family: number) => void]' is not assignable to type '[ZodTypeAny, ...ZodTypeAny[]]'.
    Type at positions 1 through 2 in source is not compatible with type at position 1 in target.
      Type 'ZodString | ((err: Error, address: string, family: number) => void)' is not assignable to type 'ZodTypeAny'.
        Type '(err: Error, address: string, family: number) => void' is missing the following properties from type 'ZodType<any, any, any>': _type, _output, _input, _def, and 30 more.

What I pretend is generating names for the arguments of the callback on the callback function for Typescript Declarations. The only way I found that could do it was using z.function().implement(). Is there another way?

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:11

github_iconTop GitHub Comments

1reaction
DarkenLMcommented, Mar 26, 2022

@andresgutgon After tinkering around with your solution, I managed to make it work. You have my deepest appreciation.

For anyone who may find this issue with the same problem, here’s the final schema:

const allowedFamilyNumbers = [0, 4, 6];
const family = z
    .number()
    .refine((num: number) => allowedFamilyNumbers.includes(num))
    .default(0)
    .optional();
const options = z.object({
    family,
    hints: z.number().optional(),
    all: z.boolean().optional(),
    verbatim: z.boolean().optional()
});

const errorArg = z.instanceof(Error);
const address = z.string();
const callbackArgs = z.union([
    errorArg.or(z.null()),
    address.nullable(),
    family.nullable(),
    z.unknown()
]);

const callbackFnSchema = z.function().args(callbackArgs).returns(z.void());

// Final schema
const fnTypeWithOptn = z.function(z.tuple([
    z.string(),
    options,
    callbackFnSchema
])).returns(z.void())

const fnTypeNoOptn = z.function(z.tuple([
    z.string(),
    callbackFnSchema
])).returns(z.void())

const schemaType = z.union([
    z.null(),
    fnTypeNoOptn,
    fnTypeWithOptn
])

The above schema accepts as valid:

  • null
  • a function defined like:
function lookupOne(hostname: string, options: z.infer<typeof options>, callback: z.infer<typeof callbackFnSchema>): void {
    try {
        // Process data
        callback(null, "address", 0);
    } catch (e) {
        callback(e, null, null);
    }
    return;
}
  • a function defined like:
function lookupOne(hostname: string, callback: z.infer<typeof callbackFnSchema>): void {
    try {
        // Process data
        callback(null, "address", 0);
    } catch (e) {
        callback(e, null, null);
    }
    return;
}
0reactions
andresgutgoncommented, Mar 25, 2022
Read more comments on GitHub >

github_iconTop Results From Across the Web

How To Handle Errors in Asynchronous Javascript Code ...
The first argument of the callback is usually named error, whereby if something goes wrong in the asynchronous function, then the callback gets ......
Read more >
Catching Errors thrown by callback functions - Stack Overflow
The callback throws an error which I need to catch. How can I catch an error thrown in a callback called by the...
Read more >
to call the callback with error (function) - Unexpected
Asserts that a node.js-style asynchronous function taking a single callback will call it with a truthy value as the first parameter.
Read more >
Error-First Callback in Node.js - GeeksforGeeks
Error -First Callback in Node.js is a function which either returns an error object or any successful data returned by the function.
Read more >
Error-handling callback functions - IBM
If an error-handling callback function has been specified in the application and if the value of the error parameter is NULL, the error...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found