How To Use The Yield Keyword In TypeScript?

Tim Mouskhelichvili
Tim Mouskhelichvili
• 3 minutes to read

One of the more obscure features of JavaScript and TypeScript is the generator function. Many developers have heard about or used it without knowing it, but those who understand it are rare. The generator function goes hand in hand with the yield keyword.

The yield keyword pauses the execution of a TypeScript generator function.

This article explains the yield keyword and how to use it in TypeScript with various code examples.

Let's get to it 😎.

typescript yield

To understand the yield keyword, you first need to understand generators.

What is a generator function?

A generator function is a special function that can be exited AND re-entered.

Those functions use the function* notation.

Calling a generator returns a generator object (instead of executing its body).

You need to call the next function to execute the function's body.

The next function

When called, the next function executes the function's body UNTIL the first yield expression or return statement. If the next function reaches a yield expression, the generator is put in a paused state. To resume its execution, we need to call the next function again.

The next function returns:

  • A value property that contains the yielded value.
  • A done property that indicates if the generator has yielded its last value.

What is the yield keyword?

The yield keyword pauses the execution of a generator. It also can return a value. It causes the next function to return an IteratorResult object.

You can think of it as the return keyword for generators.

You can only use it in a generator function.

Here is an example:

typescriptfunction* generator() {
    yield 'Value';
    yield 'Value2';
    console.log("End");
}

const gen = generator();

// Outputs: { "value": "Value", "done": false }
console.log(gen.next());

// Outputs: { "value": "Value2", "done": false }
console.log(gen.next());

// Outputs: 'End'
// Outputs: { "value": undefined, "done": true }
console.log(gen.next());

You can also use it to return one or multiple values.

Here is an example:

typescriptfunction* generator() {
    yield 'Value';
    yield 'Value2';
    console.log("End");
}

const gen = generator();

// Outputs: { "value": "Value", "done": false }
console.log(gen.next());

// Outputs: { "value": "Value2", "done": false }
console.log(gen.next());

// Outputs: { "value": undefined, "done": true }
console.log(gen.next());

You can also yield another generator using the yield* syntax.

Here is an example:

typescriptfunction* generator1() {
    yield 55;
    yield 54;
}

function* generator2() {
    yield 1;
    yield* generator1();
}

const iterator = generator2();

// Outputs: {value: 1, done: false}
console.log(iterator.next());

// Outputs: {value: 55, done: false}
console.log(iterator.next());

// Outputs: {value: 54, done: false}
console.log(iterator.next());

// Outputs: {value: undefined, done: true}
console.log(iterator.next());

This is called generator delegation.

How to create a TypeScript generator?

To create a generator in TypeScript, you must define a function using the function* notation. You can also use one or multiple yield statements.

Here is an example:

typescriptfunction* generator(count: number): IterableIterator<number> {
    while(true) {
        yield count++;
    }
} 

const gen = generator(1);

// Outputs:  { "value": 1, "done": false }
console.log(gen.next());

// Outputs: { "value": 2, "done": false }
console.log(gen.next());

As you can see, we first instantiate a new generator and pass an initial count value to it.

Then using the next function, we execute the function's body till the first yield expression.

The generator's execution is paused until we call the next function again.

Here is a more practical example:

typescriptfunction* fibonacci(): IterableIterator<number> {
    const f0 = 0;
    yield f0;

    const f1 = 1;
    yield f1;
    
    let previous = f0;
    let current = f1;
    let next;

    while(true) {
        next = previous + current;
        previous = current;
        current = next;

        yield next;
    }
}

const gen = fibonacci();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2

In this example, we create a function that generates the Fibonacci sequence using a generator.

Final thoughts

As you can see, the yield keyword is used in generator functions to pause their execution (and return a value).

Although you will rarely need to create a generator, it is essential for a well-rounded developer to know and understand this concept.

typescript yield

Here are some other TypeScript tutorials for you to enjoy:

Comments (0)
Reply to: