Lesson 1
Understanding Data Streams with TypeScript
Introduction: Understanding Data Streams

Warm greetings! This lesson introduces data streams, which are essentially continuous datasets. Think of a weather station or gaming application gathering data per second — both generate data streams! We will master handling these data streams using TypeScript, learning to access elements, slice segments, and convert these streams into strings for easier handling.

Representing Data Streams in TypeScript

In TypeScript, data streams can be represented using arrays, with additional TypeScript features like type annotations that improve code readability and robustness.

Consider a straightforward TypeScript class named DataStream. This class encapsulates operations related to data streams in our program:

TypeScript
1type DataElement = { id: number, value: number }; 2 3class DataStream { 4 data: DataElement[]; 5 6 constructor(data: DataElement[]) { 7 this.data = data; 8 } 9}

To use it, we create a sample data stream as an instance of our DataStream class, where each element is an object of type DataElement with two properties, id and value:

TypeScript
1const stream = new DataStream([ 2 { id: 1, value: 100 }, 3 { id: 2, value: 200 }, 4 { id: 3, value: 300 }, 5 { id: 4, value: 400 } 6]);
Accessing Elements - A Key Operation

To examine individual elements of a data stream, we use indexing. The get() method we introduce below fetches the i-th element from the data stream:

TypeScript
1type DataElement = { id: number, value: number }; 2 3class DataStream { 4 data: DataElement[]; 5 6 constructor(data: DataElement[]) { 7 this.data = data; 8 } 9 10 get(i: number): DataElement | undefined { 11 return this.data[i]; 12 } 13}

Here, we can see the get() method in action:

TypeScript
1const stream = new DataStream([ 2 { id: 1, value: 100 }, 3 { id: 2, value: 200 }, 4 { id: 3, value: 300 }, 5 { id: 4, value: 400 } 6]); 7 8console.log(stream.get(2)); // It prints: { id: 3, value: 300 } 9console.log(stream.get(-1)); // It prints: undefined

In essence, stream.get(2) fetched us { id: 3, value: 300 } — the third element (since indexing starts from 0). Remember that TypeScript does not support indexing with negative indexes, so stream.get(-1) returns undefined.

Slicing - A Useful Technique

Fetching a range of elements rather than a single one is facilitated by slicing. A slice data.slice(i, j) creates a new array containing elements from position i (inclusive) to j (exclusive) in the data stream. We introduce a slice() method to support slicing:

TypeScript
1type DataElement = { id: number, value: number }; 2 3class DataStream { 4 data: DataElement[]; 5 6 constructor(data: DataElement[]) { 7 this.data = data; 8 } 9 10 get(i: number): DataElement | undefined { 11 return this.data[i]; 12 } 13 14 slice(i: number, j: number): DataElement[] { 15 return this.data.slice(i, j); 16 } 17}

Here's a quick usage example:

TypeScript
1const stream = new DataStream([ 2 { id: 1, value: 100 }, 3 { id: 2, value: 200 }, 4 { id: 3, value: 300 }, 5 { id: 4, value: 400 } 6]); 7 8console.log(stream.slice(1, 3)); 9// It prints: [{ id: 2, value: 200 }, { id: 3, value: 300 }]
Transforming Data Streams to Strings - Another Key Operation

To gain a clearer view of our data, we may wish to convert our data streams into strings. To ensure the conversion works consistently, we will create a custom string representation for our data elements. Have a look at the toString() method in action:

TypeScript
1type DataElement = { id: number, value: number }; 2 3class DataStream { 4 data: DataElement[]; 5 6 constructor(data: DataElement[]) { 7 this.data = data; 8 } 9 10 get(i: number): DataElement | undefined { 11 return this.data[i]; 12 } 13 14 slice(i: number, j: number): DataElement[] { 15 return this.data.slice(i, j); 16 } 17 18 toString(): string { 19 return '[' + this.data.map(item => JSON.stringify(item)).join(', ') + ']'; 20 } 21}

Here's a breakdown:

  • this.data.map(item => JSON.stringify(item)): This part goes through each item in the data array, converts it to a JSON string using JSON.stringify(item), and creates a new array of these JSON string representations.

  • .join(', '): After converting each item to a JSON string, the join(', ') method takes this array of strings and combines them into a single string, with each element separated by a comma followed by a space.

  • '[' + ... + ']': Finally, this concatenates the beginning '[' and ending ']' brackets to the joined string, giving a visual representation of an array in string form.

To see it in action:

TypeScript
1const stream = new DataStream([ 2 { id: 1, value: 100 }, 3 { id: 2, value: 200 }, 4 { id: 3, value: 300 }, 5 { id: 4, value: 400 } 6]); 7 8console.log(stream.toString()); 9// It prints: [{ "id": 1, "value": 100 }, { "id": 2, "value": 200 }, 10// { "id": 3, "value": 300 }, { "id": 4, "value": 400 }]

In later lessons, we'll expand data stream functionality to include more complex data stream handling capabilities.

Lesson Summary

In this lesson, we've explored data streams, discovered how to represent and manipulate them using native TypeScript data structures, especially arrays, and encapsulated operations on data streams with TypeScript classes equipped with type annotations to enhance code safety and clarity.

Now it's time to apply your newfound knowledge in the practice exercises that follow!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.