简体   繁体   English

如何指定无限生成器的类型?

[英]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:给出了以下建议:

  1. check first if done is true and act accordingly (early return, throw, whatever you need);首先检查 done 是否为真并采取相应行动(提前返回,抛出,无论你需要什么);
  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM