簡體   English   中英

如何指定無限生成器的類型?

[英]How to specify type of an infinite generator?

這是一個示例 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 生成無限數字序列。 所以我不需要檢查它是否完成了。

是否可以消除第二種情況下的類型檢查錯誤? 這是一個類似的問題: How to avoid void type in generators Typescript 給出了以下建議:

  1. 首先檢查 done 是否為真並采取相應行動(提前返回,拋出,無論你需要什么);
  2. 如果您知道迭代器將始終返回一個值,則可以使用非空斷言。

但我不想檢查done 而且我不能添加非空斷言,因為它是 JavaScript,而不是 TypeScript。你能建議如何消除錯誤嗎?

這是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 正在保護您免受g.return()的侵害。 不存在永遠無法done的生成器 function。 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());

我不認為這是 Typescript 的問題,因為它應該會捕獲像這樣的潛在代碼錯誤。

如果您完全確定生成器不會返回 null 值,您可以像這樣顯式寫出類型: const y = (g.next().value as number) * 2;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM