科技速递|TypeScript 4.0发布,新增可变参数元组类型等( 三 )

]type Unbounded = [...Strings, ...Numbers, boolean];
通过将这两种功能结合在一起 , 就可以很便捷的编写一个类型正确的签名concat:
type Arr = readonly any[];function concat(arr1: T, arr2: U): [...T, ...U] {return [...arr1, ...arr2];}尽管一个签名仍然有些冗长 , 但这只是一个签名 , 不必重复 , 它可以在所有数组和元组上提供可预测的行为 。
功能本身很棒 , 但在更复杂的场景中也很有用 。 例如 , 函数partialCall的部分应用名为的参数 。 partialCall带有一个函数f以及几个初始的期望参数 , 返回一个新函数 , 该函数接受f仍需要的任何其他参数 , 并f在接收到它们时进行调用 。
function partialCall(f, ...headArgs) {return (...tailArgs) => f(...headArgs, ...tailArgs)}TS 4.0改进了rest参数和rest tuple元素的推断过程 , 使其"正常工作":
type Arr = readonly unknown[];function partialCall(f: (...args: [...T, ...U]) => R, ...headArgs: T) {return (...tailArgs: U) => f(...headArgs, ...tailArgs)}
partialCall了解其初始可以使用和不能使用的参数 , 并返回可以接受和拒绝的函数 。
const foo = (x: string, y: number, z: boolean) => {}// This doesn't work because we're feeding in the wrong type for 'x'.const f1 = partialCall(foo, 100);// ~~~// error! Argument of type 'number' is not assignable to parameter of type 'string'.// This doesn't work because we're passing in too many arguments.const f2 = partialCall(foo, "hello", 100, true, "oops")// ~~~~~~// error! Expected 4 arguments, but got 5.// This works! It has the type '(y: number, z: boolean) => void'const f3 = partialCall(foo, "hello");// What can we do with f3 now?f3(123, true); // works!f3();// error! Expected 2 arguments, but got 0.f3(123, "hello");// ~~~~~~~// error! Argument of type 'string' is not assignable to parameter of type 'boolean'.可变参数元组类型启用了许多新的令人兴奋的模式 , 尤其是在函数组成方面 , 可以利用它来做更好的工作 , 以检查JavaScript的内置bind方法的类型 。
元组元素标签改善元组类型和参数列表非常重要 , 围绕常见的JavaScript习惯用法进行强类型验证 。 实际上只是对参数列表进行切片和切块并将它们传递给其他函数 。 可以使用元组类型作rest参数的想法很有意义 。
例如 , 以下使用元组类型作为参数的函数
function foo(...args: [string, number]): void {// ...}…should appear no different from the following function…function foo(arg0: string, arg1: number): void {// ...}…for any caller of foo.foo("hello", 42); // worksfoo("hello", 42, true); // errorfoo("hello"); // error
差异有:可读性 。 在第一个示例中 , 没有第一个和第二个元素的参数名称 。 尽管这些对类型检查没有影响 , 但元组位置上缺少标签会使其更难使用 , 难以传达意图 。
这就是为什么要在TypeScript 4.0中 , 元组类型需要提供标签了 。
type Range = [start: number, end: number];为了加深参数列表和元组类型之间的联系 , 其余元素和可选元素的语法与参数列表的语法相同 。
type Foo = [first: number, second?: string, ...rest: any[]];使用带标签的元组时有一些规则 。 例如 , 当标记一个元组元素时 , 还必须标记该元组中的所有其他元素 。


推荐阅读