[英]How to specify type of an infinite generator?
Here is a sample JavaScript code:这是一个示例 JavaScript 代码:
/**
* Generates the sequence of numbers.
*
* @param {number} i - The first number.
* @yields {number} The next number.
*/
function* gen(i) {
while (true) {
yield i++;
}
}
const g = gen(1);
// 1st case
// No error here
const n = g.next();
if (!n.done) {
const x = n.value * 2;
console.log(x);
}
// 2nd case
// Error:
// The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
// Other variants of the error for other 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)
gen
function generates an infinte sequence of numbers. gen
function 生成无限数字序列。 So I don't need to check whether it's finished.所以我不需要检查它是否完成了。
Is it possible to remove the typecheck error in the 2nd case?是否可以消除第二种情况下的类型检查错误? Here is a similar question: How to avoid void type in generators Typescript .这是一个类似的问题: How to avoid void type in generators Typescript 。 The following suggestions was given:给出了以下建议:
- check first if done is true and act accordingly (early return, throw, whatever you need);首先检查 done 是否为真并采取相应行动(提前返回,抛出,无论你需要什么);
- if you know that the iterator will always return a value you can use a non-null assertion.如果您知道迭代器将始终返回一个值,则可以使用非空断言。
But I don't want to check done
.但我不想检查done
。 And I can't add a non-null assertion, because it's JavaScript, not TypeScript. Could you suggest how to remove the error?而且我不能添加非空断言,因为它是 JavaScript,而不是 TypeScript。你能建议如何消除错误吗?
Here is jsconfig.json
:这是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"]
}
TypeScript is protecting you from g.return()
. TypeScript 正在保护您免受g.return()
的侵害。 There does not exist a generator function which can never be done
.不存在永远无法done
的生成器 function。 The Generator.prototype.return()
method can even be implicitly called when using generator objects in for...of
loops:在for...of
循环中使用生成器对象时,甚至可以隐式调用Generator.prototype.return()
方法:
function* gen(i) { while (true) { yield i++; } } const g = gen(1); for (const n of g) { if (n > 5) break; console.log(n); } console.log(g.next());
I don't think this is a problem with Typescript, since it is supposed to catch potential code errors like this.我不认为这是 Typescript 的问题,因为它应该会捕获像这样的潜在代码错误。
If you're absolutely certain that the generator will not return a null value, you could explicitly write out the type like so: const y = (g.next().value as number) * 2;
如果您完全确定生成器不会返回 null 值,您可以像这样显式写出类型: const y = (g.next().value as number) * 2;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.