Cog*_*Cog 4 javascript types flowtype flow-typed
有人可以解释“可选函数参数”和“可能类型”之间的区别吗,如 Flow 文档的这一页所述?
这些定义听起来非常相似:
也许类型: “也许类型用于值是可选的地方”
可选函数参数: “函数可以有可选参数,其中问号 ? 出现在参数名称之后。”
我从语法的角度理解这些差异。但是,听起来两者都可以用于您想要为函数定义可选参数的情况。你会在哪里使用一个?
没有区别。但它们也是完全不同的东西。
我认为这里有一些概念上的混淆。下面是一个可选参数的例子:
function recase(str, lower) {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
recase('Test', true)
// "test"
recase('test')
// "TEST"
recase()
// Uncaught TypeError: Cannot read property 'toUpperCase' of undefined
Run Code Online (Sandbox Code Playgroud)
我们的函数有两个参数。第一个是必需的,如果我们不传递至少一个参数,该函数将抛出异常。第二个是可选的,如果我们不传递第二个,则不会抛出异常,返回的值将不同。
请注意,我没有介绍任何类型。这是因为这里的“可选参数”只是一个通用的编程概念。Flow 没有一些称为“可选参数”的内在特征。Flow 提供的是一种输入可选参数的方法,称为“可能类型”。
所以说我想在上面输入我的函数。好吧,第一遍可能是这样的:
// We're taking a string and a boolean and returning a string, right?
function recase(str: string, lower: boolean): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
recase('Test', false)
// "TEST"
recase('Test', true)
// "test"
recase('Test')
// ^ Cannot call `recase` because function [1] requires another argument.
Run Code Online (Sandbox Code Playgroud)
由于我们输入loweras boolean,flow 期望将 aboolean作为第二个参数传递。当我们不传递布尔值时,流会抛出错误。我们的参数不再是可选的。我们可以只从 中删除类型lower,但随后 flow 将默认lower为该any类型,这意味着用户可以传递他们想要的任何内容,这使得我们的类型模棱两可且容易出错。这是我们可以做的一件事:
function recase(str: string, lower: void | boolean): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
recase('Test', true)
// "test"
recase('Test')
// "TEST"
Run Code Online (Sandbox Code Playgroud)
在流中,void类型只匹配 的值undefined。如果我们lower在调用 时不提供 值recase,则 的值lower将是undefined,并通过键入lower 就像void | boolean我们告诉流的那样lower可以是 aboolean或undefined(未指定为参数)。
显然,这是一个非常常见的场景。事实上如此普遍以至于在某些时候我们可能会考虑封装它。这可以通过泛型来完成,如下所示:
// Let's call this Q for "Question" but it's nice and short
type Q<T> = void | null | T;
function recase(str: string, lower: Q<boolean>): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
Run Code Online (Sandbox Code Playgroud)
请注意,我们已添加null到我们的泛型类型中,因为这种undefined情况与null希望能够传入null可选参数的情况有很多重叠。
嗯,这很常见,以至于 flow 为我们提供了一种相当于这种情况的语法糖,称为“也许类型”。如果您能够将我们的Q类型重命名为,?那么您基本上可以拥有类型。
function recase(str: string, lower: ?boolean): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
Run Code Online (Sandbox Code Playgroud)