TypeScript 4.0で実現!Promise型のアンラップ

2024-04-02

TypeScriptにおけるPromise型のアンラップ

thenメソッドを使う

最も一般的な方法は、thenメソッドを使う方法です。

const promise: Promise<string> = new Promise((resolve) => {
  resolve('Hello, world!');
});

promise.then((value) => {
  // valueはstring型であることが保証される
  console.log(value); // "Hello, world!"が出力される
});

この方法はシンプルで分かりやすいですが、ネストが深くなると可読性が悪くなる可能性があります。

async/awaitを使う

非同期処理をより直感的に記述できるasync/awaitを使う方法もあります。

async function getData(): Promise<string> {
  return new Promise((resolve) => {
    resolve('Hello, world!');
  });
}

async function main() {
  const data = await getData();
  // dataはstring型であることが保証される
  console.log(data); // "Hello, world!"が出力される
}

main();

この方法は可読性が高いですが、すべての状況で使用できるわけではありません。

Promise.prototype.thenプロパティを使って、thenメソッドを直接呼び出す方法もあります。

const promise: Promise<string> = new Promise((resolve) => {
  resolve('Hello, world!');
});

Promise.prototype.then.call(promise, (value) => {
  // valueはstring型であることが保証される
  console.log(value); // "Hello, world!"が出力される
});

この方法はあまり一般的ではありませんが、より柔軟な記述が可能です。

型ガードを使う

TypeScript 4.0以降では、型ガードを使ってPromise型のアンラップを行うことができます。

const promise: Promise<string | number> = new Promise((resolve) => {
  if (Math.random() > 0.5) {
    resolve('Hello, world!');
  } else {
    resolve(42);
  }
});

const value = await promise;

if (typeof value === 'string') {
  // valueはstring型であることが保証される
  console.log(value); // "Hello, world!"が出力される
} else {
  // valueはnumber型であることが保証される
  console.log(value); // 42が出力される
}

この方法は、型安全かつ柔軟な記述が可能です。

上記の方法のどれを使うかは、状況によって異なります。可読性、簡潔性、型安全性などを考慮して、最適な方法を選びましょう。




thenメソッドを使う

const promise: Promise<string> = new Promise((resolve) => {
  resolve('Hello, world!');
});

promise.then((value) => {
  // valueはstring型であることが保証される
  console.log(value); // "Hello, world!"が出力される
});

async/awaitを使う

async function getData(): Promise<string> {
  return new Promise((resolve) => {
    resolve('Hello, world!');
  });
}

async function main() {
  const data = await getData();
  // dataはstring型であることが保証される
  console.log(data); // "Hello, world!"が出力される
}

main();

Promise.prototype.thenを使う

const promise: Promise<string> = new Promise((resolve) => {
  resolve('Hello, world!');
});

Promise.prototype.then.call(promise, (value) => {
  // valueはstring型であることが保証される
  console.log(value); // "Hello, world!"が出力される
});

型ガードを使う

const promise: Promise<string | number> = new Promise((resolve) => {
  if (Math.random() > 0.5) {
    resolve('Hello, world!');
  } else {
    resolve(42);
  }
});

const value = await promise;

if (typeof value === 'string') {
  // valueはstring型であることが保証される
  console.log(value); // "Hello, world!"が出力される
} else {
  // valueはnumber型であることが保証される
  console.log(value); // 42が出力される
}

実行方法

tsc filename.ts
node filename.js

出力結果

Hello, world!



Promise型のアンラップ方法

Promise.allを使う

複数のPromiseをまとめて処理したい場合に有効な方法です。

const promise1: Promise<string> = new Promise((resolve) => {
  resolve('Hello, ');
});

const promise2: Promise<string> = new Promise((resolve) => {
  resolve('world!');
});

Promise.all([promise1, promise2]).then((values) => {
  // valuesは[string, string]型の配列であることが保証される
  const message = values.join('');
  console.log(message); // "Hello, world!"が出力される
});

Promise.raceを使う

const promise1: Promise<string> = new Promise((resolve) => {
  setTimeout(() => resolve('Hello, '), 1000);
});

const promise2: Promise<string> = new Promise((resolve) => {
  setTimeout(() => resolve('world!'), 500);
});

Promise.race([promise1, promise2]).then((value) => {
  // valueはstring型であることが保証される
  console.log(value); // "world!"が出力される
});

自作のヘルパー関数を使う

上記の方法でニーズを満たせない場合は、自作のヘルパー関数を作成する方法もあります。

function unwrapPromise<T>(promise: Promise<T>): T {
  const result = await promise;
  return result;
}

const promise: Promise<string> = new Promise((resolve) => {
  resolve('Hello, world!');
});

const value = unwrapPromise(promise);

console.log(value); // "Hello, world!"が出力される

Promise型のアンラップには様々な方法があります。状況に合わせて最適な方法を選びましょう。


typescript promise


TypeScriptインターフェース:ジェネリック型、asキーワード、Object.assign を駆使したオブジェクト作成

リテラル構文を使用する最も簡単な方法は、リテラル構文を使用することです。インターフェースで定義されたプロパティ名と型を一致させ、値を指定します。new キーワードを使用するインターフェースと一致するコンストラクタを持つクラスを作成することもできます。...


TypeScript初心者でもわかる!String型とstring型の使い分け

String型とstring型は、基本的に同じ意味で、文字列を表す型です。唯一の違いは、String型はオブジェクト型であるのに対し、string型はプリミティブ型であることです。詳細:String型: Stringというクラスのインスタンスを表します。 メソッドやプロパティを持ちます。...


もう迷わない!TypeScript除外型の使い道とサンプルコード集

以下は、'exclude-string'という文字列を除いたすべての文字列値を表す型を定義する例です。この型を使用すると、以下のようになります。value 変数には、'exclude-string'以外の任意の文字列を代入できます。一方、value2 変数には 'exclude-string' を代入することはできません。...


TypeScript: 型 'string | undefined' は型 'string' に割り当て可能ではありません

string | undefined 型は、文字列または undefined のいずれかの値を持つことができる型です。一方、string 型は、文字列のみを値として持つ型です。つまり、string | undefined 型の変数には、undefined という値が格納される可能性があるため、string 型の変数に直接割り当てることはできないのです。...


TypeScript & Reduxで開発をさらに効率化! Next.jsとCreate React Appの活用術

React. jsは、Webアプリケーション開発で人気のあるJavaScriptライブラリです。しかし、単体のライブラリとしてだけでなく、開発をさらに効率化するためのツールやフレームワークも豊富に存在します。その中でもよく比較されるのが、Create React AppとNext...