Typescript 数组分解分配中的NonuCheckedIndexedAccess类型断言

Typescript 数组分解分配中的NonuCheckedIndexedAccess类型断言,typescript,tuples,Typescript,Tuples,使用noUncheckedIndexedAccess,数组访问现在返回T | undefined,以反映您可能正在访问过去的.length。有时你知道你不是,可以使用类型断言,告诉TypeScript忘记它 但我不知道在这种情况下怎么做: 功能双功能(x:数字[]):数字[]{ 返回x.map(a=>a*2) } 函数foo(){ 设a:number=5; 设b:number=6; [a,b]=双([b,a]); } 我的第一个猜测是 [a!b!]=double([b,a]); 但它不起作用

使用
noUncheckedIndexedAccess
,数组访问现在返回
T | undefined
,以反映您可能正在访问过去的
.length
。有时你知道你不是,可以使用
类型断言,告诉TypeScript忘记它

但我不知道在这种情况下怎么做:

<代码>功能双功能(x:数字[]):数字[]{ 返回x.map(a=>a*2) } 函数foo(){ 设a:number=5; 设b:number=6; [a,b]=双([b,a]); }
我的第一个猜测是

[a!b!]=double([b,a]);
但它不起作用。有没有一种不乏味的方法可以做到这一点


也许只是把它转换成一个元组

function double(x: number[]): number[] {
  return x.map(a => a * 2)
}

function foo() {
  let a: number = 5;
  let b: number = 6;
  [a, b] = double([b, a]) as [number, number];
}

也许只是把它转换成元组

function double(x: number[]): number[] {
  return x.map(a => a * 2)
}

function foo() {
  let a: number = 5;
  let b: number = 6;
  [a, b] = double([b, a]) as [number, number];
}

这是如何在标准库中的
ReadonlyArray
接口(以及通常的
ReadonlyArray
接口)上定义
map
方法的一个缺点:无论输入类型是否为元组,它都返回可变数组:

接口只读阵列{
映射(callbackfn:(值:T,索引:number,数组:readonly T[])=>U,thisArg?:any):U[]
}
由于
ReadonlyArray
中的值类型是由泛型类型参数
T
确定的,因此无法确定索引和值之间的精确关系,这对于能够返回元组至关重要

一种本质上不安全但简单的方法是使用类型断言,将
作为
使用(它本身没有问题,因为您的情况恰恰是您比编译器知道更多的情况)

您可能知道的另一个更安全但繁琐的解决方案是将变量定义为
number | undefined
(如果您定义一个helper
MaybeNum
或类似的工具,那么就不那么繁琐了),然后使用类型保护来保证编译器的安全

最后,您可以利用声明合并技术,为
map
方法提供自己的重载,该方法将使用
this
推断来获取元组类型。使用它,您可以返回一个映射类型,其中的值由推断的
U
替换:

接口只读阵列{
map(callbackfn:(值:T,索引:number,数组:readonly T[])=>U,thisArg?:any:{[P in keyof this]:U};
}
您的
double
函数现在只需调整一下即可告诉编译器
x
将成为一个
readonly
数组:

constdbl=(x:T)=>x.map(a=>a*2);
结果正是您想要的(显然,当您传递数组文本以将其视为元组时,
as const
是必需的,但这是一个很小的代价),而且,
ReadonlyArray
方法仍然可以正确使用:

函数foo2(){
设a:number=5;
设b:number=6;
[a,b]=dbl([b,a]作为常量);//好的
}
dbl([5,6]作为const.forEach((a)=>console.log(a))//好的,这里有一个号码

这是标准库中的
ReadonlyArray
接口(以及通常的
ReadonlyArray
接口)上如何定义
map
方法的一个缺点:无论输入类型是否为元组,它都返回可变数组:

接口只读阵列{
映射(callbackfn:(值:T,索引:number,数组:readonly T[])=>U,thisArg?:any):U[]
}
由于
ReadonlyArray
中的值类型是由泛型类型参数
T
确定的,因此无法确定索引和值之间的精确关系,这对于能够返回元组至关重要

一种本质上不安全但简单的方法是使用类型断言,将
作为
使用(它本身没有问题,因为您的情况恰恰是您比编译器知道更多的情况)

您可能知道的另一个更安全但繁琐的解决方案是将变量定义为
number | undefined
(如果您定义一个helper
MaybeNum
或类似的工具,那么就不那么繁琐了),然后使用类型保护来保证编译器的安全

最后,您可以利用声明合并技术,为
map
方法提供自己的重载,该方法将使用
this
推断来获取元组类型。使用它,您可以返回一个映射类型,其中的值由推断的
U
替换:

接口只读阵列{
map(callbackfn:(值:T,索引:number,数组:readonly T[])=>U,thisArg?:any:{[P in keyof this]:U};
}
您的
double
函数现在只需调整一下即可告诉编译器
x
将成为一个
readonly
数组:

constdbl=(x:T)=>x.map(a=>a*2);
结果正是您想要的(显然,当您传递数组文本以将其视为元组时,
as const
是必需的,但这是一个很小的代价),而且,
ReadonlyArray
方法仍然可以正确使用:

函数foo2(){
设a:number=5;
设b:number=6;
[a,b]=dbl([b,a]作为常量);//好的
}
dbl([5,6]作为const.forEach((a)=>console.log(a))//好的,这里有一个号码