How to fix Cannot use 'yield' in non-generator function in TypeScript

TypeScriptINTERMEDIATEMEDIUMUpdated Dec 11, 2025· 93 views

This error occurs when you use the yield keyword in a regular function instead of a generator function. Generator functions must be declared with the function* syntax (with an asterisk).

Quick fix

Fixes Cannot use 'yield' in non-generator function

// ❌ Wrong - regular function
function getNumbers() {
  yield 1;
  yield 2;
  yield 3;
}

// ✅ Correct - generator function
function* getNumbers() {
  yield 1;
  yield 2;
  yield 3;
}
  1. Add the asterisk (*) to make it a generator function
  2. Add proper return type annotation for generators
  3. Convert arrow functions to function* syntax
  4. Verify your tsconfig.json target supports generators
typescript — error
// ❌ Wrong - regular function
function getNumbers() {
yield 1;
yield 2;
yield 3;
}
// ✅ Correct - generator function
function* getNumbers() {
yield 1;
yield 2;
yield 3;
}
Cannot use 'yield' in non-generator function

What this error means

This TypeScript error occurs when you attempt to use the yield keyword inside a function that hasn't been declared as a generator function. In JavaScript and TypeScript, the yield keyword is a special operator that can only be used within generator functions, which are denoted by the function* syntax (note the asterisk). Generator functions are special functions that can pause their execution and resume later, yielding multiple values over time. When you call a generator function, it returns a generator object that implements the iterator protocol, allowing you to retrieve values one at a time using the next() method. The compiler enforces this restriction because using yield in a regular function would violate the language specification. Regular functions execute from start to finish in a single run, while generator functions maintain their state between yields and can be paused and resumed multiple times.

Typical symptoms

  • TypeScript compilation fails with "Cannot use 'yield' in non-generator function" error
  • IDE shows red underline beneath the yield keyword
  • Build process fails when transpiling TypeScript to JavaScript
  • Error occurs even though similar JavaScript code works in the browser

Common causes

  1. Using yield keyword in a regular function declared with "function" instead of "function*"
  2. Using yield in an arrow function, which cannot be generator functions
  3. Attempting to use yield in a class method without the asterisk syntax
  4. Copying generator code into a regular function context
  5. TypeScript target is set to ES3 or ES5 without proper downlevel iteration support

How to fix "Cannot use 'yield' in non-generator function"

1Add the asterisk (*) to make it a generator function

The most common fix is to change your function declaration to use the function* syntax:

typescript
// ❌ Wrong - regular function
function getNumbers() {
  yield 1;
  yield 2;
  yield 3;
}

// ✅ Correct - generator function
function* getNumbers() {
  yield 1;
  yield 2;
  yield 3;
}

For class methods, add the asterisk before the method name:

typescript
class DataGenerator {
  // ❌ Wrong
  getData() {
    yield 'data';
  }

  // ✅ Correct
  *getData() {
    yield 'data';
  }
}
2Add proper return type annotation for generators

TypeScript allows you to specify the type of values yielded by a generator function:

typescript
// Generator that yields numbers
function* numberGenerator(): Generator<number> {
  yield 1;
  yield 2;
  yield 3;
}

// Generator with yield type, return type, and next parameter type
function* advancedGenerator(): Generator<number, string, boolean> {
  const shouldContinue = yield 1;
  if (shouldContinue) {
    yield 2;
  }
  return 'done';
}

The Generator<T, TReturn, TNext> type takes three type parameters:
- T: Type of values yielded by the generator
- TReturn: Type of the final return value (default: any)
- TNext: Type of values passed to .next() (default: unknown)

3Convert arrow functions to function* syntax

Arrow functions cannot be generators. If you need generator functionality, convert to a function declaration or expression:

typescript
// ❌ Wrong - arrow functions cannot be generators
const gen = () => {
  yield 1;
};

// ✅ Correct - use function expression
const gen = function* () {
  yield 1;
};

// ✅ Also correct - use function declaration
function* gen() {
  yield 1;
}

If you need the this context from an arrow function, consider using a regular generator with .bind() or restructuring your code.

4Verify your tsconfig.json target supports generators

Generator functions were introduced in ES2015 (ES6). Ensure your TypeScript configuration targets ES2015 or higher:

json
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2015",  // or "ES6", "ES2020", "ESNext", etc.
    "lib": ["ES2015"],
    // If targeting ES5, enable downlevelIteration
    "downlevelIteration": true
  }
}

If you must target ES5 or ES3, enable the downlevelIteration flag to allow TypeScript to emit helper code for generators. Note that this increases bundle size.

5Use generator delegation with yield* for nested generators

If you're composing generators, use yield* to delegate to another generator:

typescript
function* innerGenerator() {
  yield 1;
  yield 2;
}

function* outerGenerator() {
  yield 0;
  // Delegate to another generator
  yield* innerGenerator();
  yield 3;
}

const gen = outerGenerator();
console.log([...gen]); // [0, 1, 2, 3]

This allows you to compose multiple generators while maintaining the generator context.

6Consider alternatives if generators are not needed

If you don't actually need lazy evaluation or the ability to pause execution, consider using regular functions with arrays:

typescript
// Instead of a generator
function* getNumbers() {
  yield 1;
  yield 2;
  yield 3;
}

// Use a regular function returning an array
function getNumbers(): number[] {
  return [1, 2, 3];
}

// Or return an iterator without using yield
function getNumbers(): IterableIterator<number> {
  let index = 0;
  return {
    [Symbol.iterator]() {
      return this;
    },
    next() {
      if (index < 3) {
        return { value: ++index, done: false };
      }
      return { value: undefined, done: true };
    }
  };
}

Choose generators when you need lazy evaluation, infinite sequences, or stateful iteration.

Advanced notes

Async Generators: TypeScript also supports async generators using async function* syntax, which allows you to use both await and yield together:

typescript
async function* fetchPages(urls: string[]): AsyncGenerator<Response> {
  for (const url of urls) {
    const response = await fetch(url);
    yield response;
  }
}

Generator Types in Libraries: When working with libraries like Redux-Saga, you'll encounter typed generator functions extensively. The saga middleware relies on generator functions to manage side effects in a testable, synchronous-looking manner.

Performance Considerations: Generators create iterator objects and maintain state between yields, which has a small memory overhead compared to simple functions. For hot code paths processing millions of items, consider profiling before using generators.

Iterator Protocol: Generator functions automatically implement the iterable protocol, meaning they work with for...of loops, spread operators, and destructuring. This makes them powerful for creating custom iteration logic:

typescript
function* fibonacci(): Generator<number> {
  let [prev, curr] = [0, 1];
  while (true) {
    yield curr;
    [prev, curr] = [curr, prev + curr];
  }
}

// Take first 10 fibonacci numbers
const first10 = [];
for (const num of fibonacci()) {
  if (first10.length >= 10) break;
  first10.push(num);
}

Strict Mode: In strict mode (which TypeScript enables by default), using yield as a variable name is also prohibited, even outside generator functions.

Frequently asked questions

What does "Cannot use 'yield' in non-generator function" mean?
This TypeScript error occurs when you attempt to use the yield keyword inside a function that hasn't been declared as a generator function. In JavaScript and TypeScript, the yield keyword is a special operator that can only be used within generator functions, which are denoted by the function* syntax (note the asterisk). Generator functions are special functions that can pause their execution and resume later, yielding multiple values over time.
How do I fix "Cannot use 'yield' in non-generator function"?
This error occurs when you use the yield keyword in a regular function instead of a generator function. Generator functions must be declared with the function* syntax (with an asterisk).
What causes "Cannot use 'yield' in non-generator function"?
Using yield keyword in a regular function declared with "function" instead of "function*" Using yield in an arrow function, which cannot be generator functions Attempting to use yield in a class method without the asterisk syntax
Is the "Cannot use 'yield' in non-generator function" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading