Below is an example of JavaScript code:
/**
* Generates a sequence of numbers.
*
* @param {number} i - The starting number.
* @yields {number} The next number.
*/
function* gen(i) {
while (true) {
yield i++;
}
}
const g = gen(1);
// Case 1
// No errors here
const n = g.next();
if (!n.done) {
const x = n.value * 2;
console.log(x);
}
// Case 2
// Error:
// The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
// Other variations of the error may occur for different expressions:
// Type 'number | void' is not assignable to type 'number'.
// Type 'void' is not assignable to type 'number'
const y = g.next().value * 2;
console.log(y)
The gen
function creates an infinite sequence of numbers, so checking if it's finished is unnecessary.
Is there a way to eliminate the typecheck error in the second case? A related question can be found here: How to avoid void type in generators Typescript. Some suggestions were provided:
- Check first if 'done' is true and handle accordingly (early return, throw, etc.);
- If you know that the iterator will always return a value, you can use a non-null assertion.
I prefer not to check done
, and as it's JavaScript and not TypeScript, I cannot add a non-null assertion. Any ideas on how to resolve this error?
Here is the content of jsconfig.json
:
{
"compilerOptions": {
"lib": ["es2021"],
"allowJs": true,
"checkJs": true,
"noEmit": true,
"module": "es2022",
"target": "es2021",
"strict": true,
"strictPropertyInitialization": false,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"allowUnusedLabels": false,
"allowUnreachableCode": false,
"exactOptionalPropertyTypes": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noPropertyAccessFromIndexSignature": true,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"importsNotUsedAsValues": "error"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}