Typescript: implicit params function type

I want to get a qualified type for functions that are given as parameters. This type I expect to either be a parameterless function that returns a void (Action) function that includes parameters, or a void function that it returns itself.

Here's the code I want to use:

interface JsonArray extends Array<string | number | boolean | Date | Json | JsonArray> { }

interface Json {
    [x: string]: string | number | boolean | Date | Json | JsonArray;
}

type Action = (arg1: string, arg2: Json | JsonArray) => void;
type ReturningAction = () => Action;

function required(arg1: string, ...validationFunctions: Array<ReturningAction | Action>) {
    console.log("Test");
}

function oneOf(arg1: string): (arg1: string, arg2: Json | JsonArray) => void {
    return (arg1: string, arg2: Json | JsonArray) => {
        console.log("Testing");
    }
}

function notEmpty(): (arg1: string, arg2: Json | JsonArray) => void {
    return (arg1: string, arg2: Json | JsonArray) => {
        console.log("Empty");
    }
}

required("field", oneOf); // Shouldn't be accepted
required("field", oneOf("test")) // Should be accepted
required("field", notEmpty); // Should be accepted

      

However, TypeScript seems to be ignoring additional parameters in the function definition than it expects. Can this be solved?

Even when I do the following:

function required(arg1: string, ...validationFunctions: Array<(arg1: string, arg2: Json | JsonArray) => void>) {
    console.log("Test");
}

required("field", oneOf); // Shouldn't be accepted
required("field", oneOf("test")) // Should be accepted
required("field", notEmpty); // Shouldn't be accepted
required("field", notEmpty()); // Should be accepted

      

All are accepted for some reason, however only callable functions apply.

+3


source to share


1 answer


As I said, TypeScript allows you to pass a function with fewer parameters (for example, it oneOf()

takes one parameter) to something that expects a function with more parameters (in which case it validationFunctions[0]

must take two parameters, counting that Action

). This is because a function can always ignore additional parameters passed in and throwing an error, leading to annoying errors elsewhere (as explained in the linked section in the TypeScript FAQ section).

EDIT: This assumes you are using a compiler option strictNullChecks

.

A workaround is to declare your functions oneOf

and notEmpty

so that they work like normal, but not be interpreted as values Action

:

function oneOf(arg1: string, nope?: never): (arg1: string, arg2: Json | JsonArray) => void {...}

function notEmpty(nope?: never): (arg1: string, arg2: Json | JsonArray) => void {...}

      



Note the addition of the parameter nope

in each case. You should now receive errors expecting them. Since it nope

is an optional parameter, you can leave it, and since it has a type never

, you pretty much have to leave it. So it doesn't change the way the functions are used.


There are other patches, but they are more difficult ... for example, you can make Action

and ReturningAction

non-functional type that contains the function you want to call.

Hope it helps.

+1


source







All Articles