如何在 TypeScript 中循环元组数组?例如
for (const [x, y] of [['a', 1], ['b', 2]]) {
y + 1;
}
Run Code Online (Sandbox Code Playgroud)
抱怨:
error TS2365: Operator '+' cannot be applied to types 'string | number' and '1'.
Run Code Online (Sandbox Code Playgroud)
如果我理解正确的话,TypeScript 会推断(string | number)[][]循环表达式的类型,这就是为什么循环变量y具有类型string | number,尽管实际上它只能具有类型number?
我认为https://github.com/microsoft/TypeScript/issues/3369是阻止 TypeScript 推断合适类型的问题。循环元组数组的当前解决方案是什么?类型断言?
只需添加 TS 应该理解结构的类型注释即可。它还不能从集合中推断出来。
const array: [string, number][] = [['a', 1], ['b', 2]];
for (const [x, y] of array) {
y + 1;
}
Run Code Online (Sandbox Code Playgroud)
另外我想提一下,在处理二维关联时,我认为更好的数据结构是 Map:
const myMap = new Map<string, number>([['a', 1], ['b', 2]]);
for (const [x, y] of [...myMap]) {
console.log(y + 1);
}
Run Code Online (Sandbox Code Playgroud)
高级:自定义迭代
如果元组的逻辑是一致的,那么您可以使用Symbol.iterator著名的符号创建自己的可迭代对象:
class TupleMaker implements Iterable<[string, number]> {
private next = 0;
constructor(private endsAt: number = 0) {}
private increment(): void {
this.next++;
}
*[Symbol.iterator](): Generator<[string, number]> {
const alpha = Array.from(Array(26)).map((e, i) => i + 65);
const alphabet = alpha.map((x) => String.fromCharCode(x).toLocaleLowerCase());
while (this.next < this.endsAt) {
yield [alphabet[this.next], this.next + 1];
this.increment();
}
}
}
for (const [x, y] of new TupleMaker(13)) {
console.log(y + 1);
}
Run Code Online (Sandbox Code Playgroud)
它们也可以是异步的,使用Symbol.asyncIterator
真正的问题是 的类型[['a', 1], ['b', 2]]根本不是元组类型。它将是数组类型(string | number)[][]。所以解构时x和y都会是string | number。Typescript 只会在特定情况下推断元组(例如约束为数组的类型参数或断言as const)。
如果您使用as const断言来获取打字稿来推断元组类型,并且一切都会按预期工作:
for (const [x, y] of [['a', 1], ['b', 2]] as const) {
y + 1;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7932 次 |
| 最近记录: |