In a React component I have something similar to:
if (props.someArray){ // typecheck because someArray is of type 'things[] | undefined'
props.someArray.forEach((element, i) => {
someFunction(i, element, props.someArray); // error despite typecheck (due to "| undefined")
});
}
// The functions someArray argument's type is only 'things[]', not 'things[] | undefined'
const someFunction = (i: number, element: thing, someArray: things[]) => {
someArray[i] = // do some stuff;
}
Since the typecheck is already done before the loop, is it really necessary to do it again before calling the function inside the loop? (inconveniently checking on every iteration instead of just once before looping).
if (props.someArray){ // <- I'd like to keep just this
props.someArray.forEach((element) => {
if (props.someArray) { // <- is this really necessary?
someFunction(element, props.someArray);
}
});
}
Array.prototype.forEach
uses a closure (ie an entirely separate function
) for the loop body, and TypeScript is cautious about how type-information passes between function boundaries.
forEach
will invoke the callback because any script can simply overwrite or replace the default Array.prototype.forEach
implementation and do something silly, like repeatedly invoke the function on only the first element or something. If you use for(of)
instead then you won't have any problems because it doesn't use a closure: as it's a native language construct the TypeScript type engine (is that a word?) can reason about it more than it can with .forEach
.
Other reasons to use for(of)
instead of forEach
:
await
inside for(of)
.break
to abort a loop (you can't abort a forEach
without using throw
).forEach
is only available on certain specific collection types ( Array
, NodeList
, and a few others).So change your code to this:
if ( props.someArray ) {
for( const el of props.someArray ) {
someFunction( el, props.someArray );
}
}
If you want to get both the array-element and its index inside the for
loop then use entries()
like so :
if ( props.someArray ) {
for( const [idx, el] of props.someArray.entries() ) {
someFunction( idx, el, props.someArray );
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.