有没有一种方法可以保护您的代码免受使用Typescript的Javascript怪癖`Array(length)vs Array(el1,el2,…)`

有没有一种方法可以保护您的代码免受使用Typescript的Javascript怪癖`Array(length)vs Array(el1,el2,…)`,javascript,typescript,Javascript,Typescript,我没有寻找复制数组的其他方法。我的问题特别是关于类型 Typescript对此类代码()没有任何异议: const sum=原始编号=>{ const numbers\u copy=新数组(…原始\u编号)//问题出在这里 const res=数字\u copy.reduce((acc,v)=>acc+v,0) console.log(res) 返回res } 总和([1,2])//3如预期 总和([1])//0!!!打字脚本也不会抱怨。您可以检查操场。数组构造函数有问题(包括此问题)。有了TS

我没有寻找复制数组的其他方法。我的问题特别是关于类型

Typescript对此类代码()没有任何异议:
const sum=原始编号=>{
const numbers\u copy=新数组(…原始\u编号)//问题出在这里
const res=数字\u copy.reduce((acc,v)=>acc+v,0)
console.log(res)
返回res
}
总和([1,2])//3如预期

总和([1])//0!!!打字脚本也不会抱怨。您可以检查操场。
数组构造函数有问题(包括此问题)。有了TSLint,您可以使用该规则禁止使用
新数组

对于ESLint,您可以使用


从参数创建数组,考虑使用<代码>数组。< /COD>替代。

< P>数组构造函数有问题(包括这一个)。有了TSLint,您可以使用该规则禁止使用
新数组

对于ESLint,您可以使用


从参数创建数组,考虑使用<代码>数组。< /P> > .< /P> < P> <代码>数组< /COD>构造函数是有问题的,没有“好”的方式给它定义一个类型定义,适用于所有用例。标准库是为它看起来像

interface ArrayConstructor {
    new(arrayLength?: number): any[];
    new <T>(arrayLength: number): T[];
    new <T>(...items: T[]): T[];
}
此时,您的原始代码将出现如下错误:

const sum_ = (original_numbers: number[]) => {
    const numbers_copy = new Array(...original_numbers) // unknown[]
    const res = numbers_copy.reduce((acc, v) => acc + v, 0) // error!
    // ---------------------------------------> ~~~   ~
    // object is of type unknown
    console.log(res)
    return res
}
const sum = (original_numbers: number[]) => {
    const numbers_copy = new Array(0, 0, ...original_numbers) // number[]
    const res = numbers_copy.reduce((acc, v) => acc + v, 0) // okay
    console.log(res)
    return res
}
sum([1, 2]) // 3 as expected
sum([1]) // 1 as expected
因为
numbers\u copy
可能不是一个数字数组。如果要解决此问题,则需要更改调用
new Array()
的方式,以便编译器确信您得到的是一个
number[]
。可能是这样的:

const sum_ = (original_numbers: number[]) => {
    const numbers_copy = new Array(...original_numbers) // unknown[]
    const res = numbers_copy.reduce((acc, v) => acc + v, 0) // error!
    // ---------------------------------------> ~~~   ~
    // object is of type unknown
    console.log(res)
    return res
}
const sum = (original_numbers: number[]) => {
    const numbers_copy = new Array(0, 0, ...original_numbers) // number[]
    const res = numbers_copy.reduce((acc, v) => acc + v, 0) // okay
    console.log(res)
    return res
}
sum([1, 2]) // 3 as expected
sum([1]) // 1 as expected
这有点傻,但是再添加两个
0
s可以确保得到一个实际的数字数组,并且
0
不会影响总和。显然,“正确”的做法是远离
新数组(…someOtherArray)
并使用许多性能良好的方法之一复制数组。不过你知道的


您面临的潜在冲突是,您可能希望TypeScript自动将您从中解救出来。问题在于,TypeScript是为JavaScript提供一个有用的静态类型系统的一个勇敢的尝试,JavaScript是动态类型的,可以说是弱类型的。它可以在运行时做各种疯狂的事情,其中一些是人们真正依赖的。如果打字稿被收紧到如此程度以防止这些,它将最终成为一种使用起来既合法又烦人的语言

因此,无论好坏,TypeScript都是。这在#3中得到了总结:TypeScript的设计目标不是应用一个健全的或“可证明正确”的类型系统。相反,目标是在正确性和生产力之间取得平衡


正确性变得比生产率更重要或更不重要(或者生产率实际上因为必须在运行时修复潜在的可捕获问题而降低)的特定点是主观的,不同的人有不同的观点。例如,您可能希望在这里概括问题,其中库签名中的
any
隐藏了潜在的问题,您更希望
unknown
可以在任何地方使用。有一个悬而未决的问题:。如果是这样的话,您可能希望给出一个数组构造函数,因为它有足够的问题,所以没有“好”的方法给它一个适用于所有用例的类型定义。标准库是为它看起来像

interface ArrayConstructor {
    new(arrayLength?: number): any[];
    new <T>(arrayLength: number): T[];
    new <T>(...items: T[]): T[];
}
此时,您的原始代码将出现如下错误:

const sum_ = (original_numbers: number[]) => {
    const numbers_copy = new Array(...original_numbers) // unknown[]
    const res = numbers_copy.reduce((acc, v) => acc + v, 0) // error!
    // ---------------------------------------> ~~~   ~
    // object is of type unknown
    console.log(res)
    return res
}
const sum = (original_numbers: number[]) => {
    const numbers_copy = new Array(0, 0, ...original_numbers) // number[]
    const res = numbers_copy.reduce((acc, v) => acc + v, 0) // okay
    console.log(res)
    return res
}
sum([1, 2]) // 3 as expected
sum([1]) // 1 as expected
因为
numbers\u copy
可能不是一个数字数组。如果要解决此问题,则需要更改调用
new Array()
的方式,以便编译器确信您得到的是一个
number[]
。可能是这样的:

const sum_ = (original_numbers: number[]) => {
    const numbers_copy = new Array(...original_numbers) // unknown[]
    const res = numbers_copy.reduce((acc, v) => acc + v, 0) // error!
    // ---------------------------------------> ~~~   ~
    // object is of type unknown
    console.log(res)
    return res
}
const sum = (original_numbers: number[]) => {
    const numbers_copy = new Array(0, 0, ...original_numbers) // number[]
    const res = numbers_copy.reduce((acc, v) => acc + v, 0) // okay
    console.log(res)
    return res
}
sum([1, 2]) // 3 as expected
sum([1]) // 1 as expected
这有点傻,但是再添加两个
0
s可以确保得到一个实际的数字数组,并且
0
不会影响总和。显然,“正确”的做法是远离
新数组(…someOtherArray)
并使用许多性能良好的方法之一复制数组。不过你知道的


您面临的潜在冲突是,您可能希望TypeScript自动将您从中解救出来。问题在于,TypeScript是为JavaScript提供一个有用的静态类型系统的一个勇敢的尝试,JavaScript是动态类型的,可以说是弱类型的。它可以在运行时做各种疯狂的事情,其中一些是人们真正依赖的。如果打字稿被收紧到如此程度以防止这些,它将最终成为一种使用起来既合法又烦人的语言

因此,无论好坏,TypeScript都是。这在#3中得到了总结:TypeScript的设计目标不是应用一个健全的或“可证明正确”的类型系统。相反,目标是在正确性和生产力之间取得平衡


正确性变得比生产率更重要或更不重要(或者生产率实际上因为必须在运行时修复潜在的可捕获问题而降低)的特定点是主观的,不同的人有不同的观点。例如,您可能希望在这里概括问题,其中库签名中的
any
隐藏了潜在的问题,您更希望
unknown
可以在任何地方使用。有一个悬而未决的问题:。如果是这样的话,你可能想给出一个答案。你在寻找一种方法使第二个结果成为
1
?我不清楚这到底是什么“错误”?不,他们没有。。。“问题来了”…什么问题。这一切似乎都像我预期的那样工作。它到底是“不正确”吗?为什么要使用新的数组()呢?您是否在寻找一种方法使第二个结果成为
1
?我不清楚这到底是什么“错误”?不,他们没有。。。“问题来了”…什么问题。这一切似乎都像我期望的那样起作用。它到底是“不正确的”吗?为什么要使用n