- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
给定一个接受单个 string[]
的函数参数myArray
.
如果我评估 .length
属性并且该属性大于 0,那么(假设我的变量不是 any
变相)它不可能用于 myArray[0]
未定义。但是,如果我启用 noUncheckedIndexedAccess
,其类型将为 string | undefined
const myFunc = (myArray: string[]) => {
if(myArray.length > 0) {
const foo = myArray[0] // now typed at 'string | undefined'
}
}
现在我可以更改 if 语句来评估
myArray[0]
, 和
undefined
如您所料,已从类型中删除。但是,如果我现在想检查数组的长度是否大于 6,该怎么办。我不想对索引 0-5 执行相同的操作以正确缩小类型。例如:
const myFunc = (myArray: string[]) => {
if(myArray[0] && myArray[1] && myArray[2] && myArray[3] && myArray[4] && myArray[5]) {
const foo = myArray[0] // now typed at 'string', but this is uggggly
}
}
有没有更优雅的方法来根据数组的长度缩小类型,还是我将不得不考虑为 TypeScript 代码库做出贡献?
最佳答案
正如您所怀疑的那样,TypeScript 不会根据对其 length
的检查自动缩小数组的类型。属性(property)。之前已在 microsoft/TypeScript#38000 中提出了这一建议。 ,标记为“太复杂”。看起来之前有人建议过,在 microsoft/TypeScript#28837 ,仍处于打开状态并标记为“等待更多反馈”。也许你可以去那个问题并留下反馈,说明为什么这样的事情对你有帮助,为什么当前的解决方案不够充分,但我不知道它会产生多大影响。无论哪种方式,我都怀疑 TS 团队现在是否正在接受拉取请求来实现这样的功能。
如果没有任何自动缩小,你可以写一个 user defined type guard function这有你想要的效果。这是一种可能的实现:
type Indices<L extends number, T extends number[] = []> =
T['length'] extends L ? T[number] : Indices<L, [T['length'], ...T]>;
type LengthAtLeast<T extends readonly any[], L extends number> =
Pick<Required<T>, Indices<L>>
function hasLengthAtLeast<T extends readonly any[], L extends number>(
arr: T, len: L
): arr is T & LengthAtLeast<T, L> {
return arr.length >= len;
}
Indices<L>
type 旨在采用单个的、相对较小的、非负的整数数字
literal type
L
并返回
union长度为
L
的数组的数字索引.另一种说法是
Indices<L>
应该是小于
L
的非负整数的并集.观察:
type ZeroToNine = Indices<10>
// type ZeroToNine = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
这种类型的工作原理是利用
recursive conditional types连同
variadic tuple types步行从
0
高达
L
.递归类型往往能正常工作,直到它们不能正常工作,这里的一个重要警告是,如果您传入
L
,事情会很奇怪,甚至会引发错误。太大,或小数,或负数,或
number
,或工会。这是这种方法的一个重要警告。
LengthAtLeast<T, L>
采用数组类型
T
和长度
L
,并返回一个对象,该对象已知在长度至少为
L
的数组的所有索引处都具有属性。 .像这样:
type Test = LengthAtLeast<["a"?, "b"?, "c"?, "d"?, "e"?], 3>
/* type Test = {
0: "a";
1: "b";
2: "c";
} */
type Test2 = LengthAtLeast<string[], 2>
/* type Test2 = {
0: string;
1: string;
} */
最后,
hasLengthAtLeast(arr, len)
是类型保护函数。如果返回
true
,然后
arr
从类型
T
缩小至
T & LengthAtLeast<T, L>
.让我们看看它的实际效果:
const myFunc = (myArray: string[]) => {
if (hasLengthAtLeast(myArray, 6)) {
myArray[0].toUpperCase(); // okay
myArray[5].toUpperCase(); // okay
myArray[6].toUpperCase(); // error, possibly undefined
}
}
看起来挺好的。编译器很高兴允许您处理
myArray[0]
和
myArray[5]
如定义,但
myArray[6]
仍然可能未定义。
null
assertion operator 可能是值得的。喜欢
myArray[0]!.toUpperCase()
而不必担心让编译器为您验证类型安全。
len
的值,那么您可能不想要脆弱的递归条件类型,而是构建更健壮但不那么灵活的东西(例如可能只适用于特定的
len
值,如
in a comment on microsoft/TypeScript#38000 的重载类型保护)。
关于typescript - 当 noUncheckedIndexedAccess 为 true 时,按长度缩小数组类型的类型安全方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69368851/
我正在尝试创建一个包含 int[][] 项的数组 即 int version0Indexes[][4] = { {1,2,3,4}, {5,6,7,8} }; int version1Indexes[
我有一个整数数组: private int array[]; 如果我还有一个名为 add 的方法,那么以下有什么区别: public void add(int value) { array[va
当您尝试在 JavaScript 中将一个数组添加到另一个数组时,它会将其转换为一个字符串。通常,当以另一种语言执行此操作时,列表会合并。 JavaScript [1, 2] + [3, 4] = "
根据我正在阅读的教程,如果您想创建一个包含 5 列和 3 行的表格来表示这样的数据... 45 4 34 99 56 3 23 99 43 2 1 1 0 43 67 ...它说你可以使用下
我通常使用 python 编写脚本/程序,但最近开始使用 JavaScript 进行编程,并且在使用数组时遇到了一些问题。 在 python 中,当我创建一个数组并使用 for x in y 时,我得
我有一个这样的数组: temp = [ 'data1', ['data1_a','data1_b'], ['data2_a','data2_b','data2_c'] ]; // 我想使用 toStr
rent_property (table name) id fullName propertyName 1 A House Name1 2 B
这个问题在这里已经有了答案: 关闭13年前。 Possible Duplicate: In C arrays why is this true? a[5] == 5[a] array[index] 和
使用 Excel 2013。经过多年的寻找和适应,我的第一篇文章。 我正在尝试将当前 App 用户(即“John Smith”)与他的电子邮件地址“jsmith@work.com”进行匹配。 使用两个
当仅在一个边距上操作时,apply 似乎不会重新组装 3D 数组。考虑: arr 1),但对我来说仍然很奇怪,如果一个函数返回一个具有尺寸的对象,那么它们基本上会被忽略。 最佳答案 这是一个不太理
我有一个包含 GPS 坐标的 MySQL 数据库。这是我检索坐标的部分 PHP 代码; $sql = "SELECT lat, lon FROM gps_data"; $stmt=$db->query
我需要找到一种方法来执行这个操作,我有一个形状数组 [批量大小, 150, 1] 代表 batch_size 整数序列,每个序列有 150 个元素长,但在每个序列中都有很多添加的零,以使所有序列具有相
我必须通过 url 中的 json 获取文本。 层次结构如下: 对象>数组>对象>数组>对象。 我想用这段代码获取文本。但是我收到错误 :org.json.JSONException: No valu
enter code here- (void)viewDidLoad { NSMutableArray *imageViewArray= [[NSMutableArray alloc] init];
知道如何对二维字符串数组执行修剪操作,例如使用 Java 流 API 进行 3x3 并将其收集回相同维度的 3x3 数组? 重点是避免使用显式的 for 循环。 当前的解决方案只是简单地执行一个 fo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我有来自 ASP.NET Web 服务的以下 XML 输出: 1710 1711 1712 1713
如果我有一个对象todo作为您状态的一部分,并且该对象包含数组列表,则列表内部有对象,在这些对象内部还有另一个数组listItems。如何更新数组 listItems 中 id 为“poi098”的对
我想将最大长度为 8 的 bool 数组打包成一个字节,通过网络发送它,然后将其解压回 bool 数组。已经在这里尝试了一些解决方案,但没有用。我正在使用单声道。 我制作了 BitArray,然后尝试
我们的数据库中有这个字段指示一周中的每一天的真/假标志,如下所示:'1111110' 我需要将此值转换为 boolean 数组。 为此,我编写了以下代码: char[] freqs = weekday
我是一名优秀的程序员,十分优秀!