打字稿:隐式无params函数类型

时间:2017-06-07 07:06:01

标签: typescript types

我想要作为参数给出的函数的限定类型。 我希望这个类型是一个没有参数的函数,它返回一个包含参数的void函数(Action)或者它返回的void函数。

这是我想要使用的代码:

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

但是看起来,TypeScript忽略了函数定义中的额外参数而不是预期。这可以解决吗?

即使我执行以下操作:

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

由于某种原因,所有人都被接受了,但只有被叫函数适用。

1 个答案:

答案 0 :(得分:1)

我认为你注意到,TypeScript allows你传递一个参数较少的函数(例如,oneOf()需要一个参数)到需要更多参数函数的东西(在这种情况下,{ {1}}应该采用两个参数,假设它是validationFunctions[0])。这是因为函数总是可以自由地忽略传入的额外参数,并且导致错误会导致其他地方出现恼人的错误(正如TypeScript FAQ的链接部分所解释的那样)。

编辑:以下假设您使用Action编译器选项。

一种解决方法是声明您的strictNullChecksoneOf函数,使其正常工作但无法解释为notEmpty值:

Action

请注意,在每种情况下都添加了function oneOf(arg1: string, nope?: never): (arg1: string, arg2: Json | JsonArray) => void {...} function notEmpty(nope?: never): (arg1: string, arg2: Json | JsonArray) => void {...} 参数。现在你应该在你期望的地方得到错误。由于nope是一个可选参数,因此您可以将其删除,因为它的类型为nope,您几乎必须将其排除在外。所以它并没有真正改变函数的使用方式。

还有其他修复但它们的重量较重......例如,您可以使neverAction成为包含您要调用的函数的非函数类型。

希望有所帮助。