Introduction
TypeScript, being a superset of JavaScript, includes the same promise mechanism as JavaScript. In TypeScript, promises are used in much the same way, with the added benefit of strong typing.
You can read about JavaScript promises here.
This feature enhances code quality and maintainability by allowing you to specify the type of value that a promise will resolve with or the type of error it might reject with.
Here’s a basic overview of how you would use promises in TypeScript:
Defining a Promise
In TypeScript, you can define a promise with a specific type for the resolved value. Here’s an example:
let myPromise: Promise<string> = new Promise((resolve, reject) => {
const condition = true;
if (condition) {
resolve("Promise resolved successfully.");
} else {
reject("Promise rejected.");
}
});
myPromise
.then((successMsg: string) => console.log(successMsg))
.catch((errorMsg: string) => console.log(errorMsg));
In this example, Promise<string>
indicates that the promise, when resolved, will provide a string value.
This constructor takes a function, called the executor, that contains the asynchronous operation. The executor function has two parameters, resolve
and reject
, which are functions themselves. resolve
is called when the operation completes successfully, and reject
is called if an error occurs.
Using Promises with Functions
Consider a function that returns a promise. You can specify the return type of the promise:
function fetchData(url: string): Promise<any> {
return fetch(url)
.then(response => response.json())
.catch(error => console.error("Error:", error));
}
fetchData('https://jsonplaceholder.typicode.com/posts/1')
.then(data => console.log(data));
Here, fetchData
returns a promise that resolves with any type (Promise<any>
). In real-world scenarios, you would replace any
with a more specific type that matches the expected data structure.
Async/Await with Promises
TypeScript also supports the async/await
syntax, which works with promises and can make asynchronous code look and behave a bit more like synchronous code:
async function fetchAndProcessData(url: string): Promise<void> {
try {
const data = await fetchData(url);
console.log(data);
// Additional processing...
} catch (error) {
console.error("Error:", error);
}
}
fetchAndProcessData('https://jsonplaceholder.typicode.com/posts/1');
In this example, async
marks the function as asynchronous, and await
is used to wait for the promise returned by fetchData
to resolve.
TypeScript and Promise Chaining
You can use TypeScript’s type checking with promise chaining as well:
function processString(str: string): Promise<number> {
return new Promise<number>((resolve, reject) => {
resolve(str.length);
});
}
myPromise
.then(processString)
.then((length: number) => console.log(`String length: ${length}`))
.catch((error: string) => console.error(error));
Here, processString
is a function that takes a string and returns a promise that resolves with a number. TypeScript checks the types throughout the chain.
Conclusion
Promises in TypeScript offer the same functionality as in JavaScript but with the added advantage of type safety.
This feature of TypeScript helps in writing more robust and less error-prone code, especially when dealing with complex asynchronous operations.
By leveraging TypeScript’s type system with promises, you can improve the clarity and predictability of your asynchronous code.