console (TypeScript)
TypeScript/JavaScript標準のコンソール出力API。型安全な使用が可能で、開発・デバッグ段階での迅速なログ出力に適している。設定不要で即座に利用可能だが、本番環境では機能制限がある。
console
consoleオブジェクトは、TypeScript/JavaScriptの標準APIとして提供されるログ出力機能です。開発時のデバッグから本番環境でのエラー追跡まで、幅広い用途で使用されます。ブラウザとNode.jsの両環境で利用可能です。
主な特徴
- 標準API - 追加のライブラリ不要
- 多様なメソッド - 用途別の豊富なログメソッド
- 視覚的な出力 - テーブル表示やグループ化
- パフォーマンス測定 - タイマー機能
- スタックトレース - エラー追跡機能
基本的な使い方
主要なログメソッド
// 一般的な情報出力
console.log("アプリケーションが起動しました");
// エラー(多くの環境で赤色表示)
console.error("エラーが発生しました:", new Error("データベース接続失敗"));
// 警告(多くの環境で黄色表示)
console.warn("非推奨のAPIを使用しています");
// 情報メッセージ
console.info("ユーザー登録が完了しました");
// デバッグメッセージ(ブラウザでは詳細レベルの設定が必要)
console.debug("デバッグ情報:", { userId: 123, action: "login" });
複数の値の出力
const user = { id: 1, name: "田中太郎" };
const score = 95;
// 複数の値を一度に出力
console.log("ユーザー:", user, "スコア:", score);
// オブジェクトの展開表示
console.log({ user, score });
// 文字列テンプレート
console.log(`${user.name}のスコアは${score}点です`);
高度なログメソッド
テーブル表示
// 配列のテーブル表示
const users = [
{ id: 1, name: "田中", age: 25, role: "管理者" },
{ id: 2, name: "鈴木", age: 30, role: "ユーザー" },
{ id: 3, name: "佐藤", age: 28, role: "ユーザー" }
];
console.table(users);
// 特定のカラムのみ表示
console.table(users, ["name", "role"]);
// オブジェクトのテーブル表示
const stats = {
total: 100,
success: 85,
failed: 15,
pending: 0
};
console.table(stats);
グループ化
console.group("ユーザー認証プロセス");
console.log("1. 認証情報を検証");
console.log("2. トークンを生成");
console.log("3. セッションを作成");
console.groupEnd();
// 折りたたみ可能なグループ
console.groupCollapsed("詳細ログ");
console.log("詳細情報1");
console.log("詳細情報2");
console.groupEnd();
// ネストされたグループ
console.group("API呼び出し");
console.log("エンドポイント: /api/users");
console.group("リクエスト");
console.log("メソッド: GET");
console.log("ヘッダー: Authorization: Bearer xxx");
console.groupEnd();
console.group("レスポンス");
console.log("ステータス: 200");
console.log("データ: [...]");
console.groupEnd();
console.groupEnd();
パフォーマンス測定
// 処理時間の測定
console.time("データ処理");
// 重い処理
const result = processLargeDataSet();
console.timeEnd("データ処理"); // 出力: データ処理: 123.456ms
// 複数のタイマーを同時に使用
console.time("全体処理");
console.time("データベース");
await fetchFromDatabase();
console.timeEnd("データベース");
console.time("計算処理");
await performCalculations();
console.timeEnd("計算処理");
console.timeEnd("全体処理");
// タイムログ(途中経過を出力)
console.time("プロセス");
console.timeLog("プロセス", "初期化完了");
// ... 処理 ...
console.timeLog("プロセス", "データ読み込み完了");
// ... 処理 ...
console.timeEnd("プロセス");
アサーションとカウント
// アサーション(条件が偽の場合のみ出力)
const age = 15;
console.assert(age >= 18, "年齢が18歳未満です", { age });
// カウンター
function processItem(item: string) {
console.count("アイテム処理");
// 処理
}
["A", "B", "C"].forEach(processItem);
// 出力:
// アイテム処理: 1
// アイテム処理: 2
// アイテム処理: 3
console.countReset("アイテム処理"); // カウンターをリセット
スタックトレース
function innerFunction() {
console.trace("関数の呼び出し履歴");
}
function middleFunction() {
innerFunction();
}
function outerFunction() {
middleFunction();
}
outerFunction();
// スタックトレースが出力される
スタイリングとフォーマット
CSS スタイル(ブラウザ環境)
// %c を使用したスタイリング
console.log(
"%c成功!%c 処理が完了しました",
"color: green; font-weight: bold; font-size: 16px;",
"color: black; font-weight: normal;"
);
// 複数のスタイル
console.log(
"%cエラー %c重大な問題が発生しました",
"background-color: red; color: white; padding: 2px 4px; border-radius: 2px;",
"color: red;"
);
フォーマット指定子
// %s - 文字列
console.log("こんにちは、%sさん", "田中");
// %d, %i - 整数
console.log("合計: %d個", 42);
// %f - 浮動小数点
console.log("平均値: %.2f", 3.14159);
// %o - オブジェクト(展開可能)
console.log("ユーザーオブジェクト: %o", { id: 1, name: "田中" });
// %O - オブジェクト(展開不可)
console.log("ユーザーオブジェクト: %O", { id: 1, name: "田中" });
TypeScript固有の実装
型安全なラッパー
// 型安全なログレベル
enum LogLevel {
DEBUG = 0,
INFO = 1,
WARN = 2,
ERROR = 3
}
class Logger {
constructor(private minLevel: LogLevel = LogLevel.INFO) {}
private shouldLog(level: LogLevel): boolean {
return level >= this.minLevel;
}
debug(...args: any[]): void {
if (this.shouldLog(LogLevel.DEBUG)) {
console.debug("[DEBUG]", ...args);
}
}
info(...args: any[]): void {
if (this.shouldLog(LogLevel.INFO)) {
console.info("[INFO]", ...args);
}
}
warn(...args: any[]): void {
if (this.shouldLog(LogLevel.WARN)) {
console.warn("[WARN]", ...args);
}
}
error(...args: any[]): void {
if (this.shouldLog(LogLevel.ERROR)) {
console.error("[ERROR]", ...args);
}
}
table(data: any, columns?: string[]): void {
if (this.shouldLog(LogLevel.DEBUG)) {
console.table(data, columns);
}
}
}
// 使用例
const logger = new Logger(LogLevel.INFO);
logger.debug("これは表示されない"); // minLevelがINFOのため
logger.info("これは表示される");
構造化ログ
interface LogEntry {
timestamp: Date;
level: string;
message: string;
context?: Record<string, any>;
}
class StructuredLogger {
private format(entry: LogEntry): string {
return JSON.stringify({
...entry,
timestamp: entry.timestamp.toISOString()
});
}
log(level: string, message: string, context?: Record<string, any>): void {
const entry: LogEntry = {
timestamp: new Date(),
level,
message,
context
};
switch (level) {
case "error":
console.error(this.format(entry));
break;
case "warn":
console.warn(this.format(entry));
break;
default:
console.log(this.format(entry));
}
}
error(message: string, error?: Error, context?: Record<string, any>): void {
this.log("error", message, {
...context,
error: error ? {
name: error.name,
message: error.message,
stack: error.stack
} : undefined
});
}
}
環境別の設定
開発/本番環境の切り替え
const isDevelopment = process.env.NODE_ENV === "development";
// 条件付きログ
if (isDevelopment) {
console.log("開発環境のデバッグ情報");
}
// console メソッドの無効化(本番環境)
if (!isDevelopment) {
console.log = () => {};
console.debug = () => {};
// エラーとワーニングは残す
}
// より洗練されたアプローチ
class ConditionalLogger {
private isDev = process.env.NODE_ENV === "development";
log(...args: any[]): void {
if (this.isDev) {
console.log(...args);
}
}
// 本番環境でも記録したい重要な情報
important(...args: any[]): void {
console.log("[IMPORTANT]", ...args);
}
}
ベストプラクティス
1. 適切なログレベルの使用
// 良い例
console.error("データベース接続エラー:", error);
console.warn("APIレート制限に近づいています");
console.info("サーバーが起動しました");
console.debug("リクエスト詳細:", requestData);
// 悪い例
console.log("エラー!!!"); // エラーにはconsole.errorを使用すべき
2. 意味のあるメッセージ
// 良い例
console.log(`ユーザー ${userId} のログイン処理完了(処理時間: ${duration}ms)`);
// 悪い例
console.log("done"); // 何が完了したか不明
console.log(data); // コンテキストがない
3. 構造化されたコンテキスト
// 良い例
console.log("注文処理エラー", {
orderId: order.id,
userId: user.id,
error: error.message,
timestamp: new Date().toISOString()
});
// 悪い例
console.log("エラー: " + order.id + " - " + user.id);
4. パフォーマンスへの配慮
// 本番環境での過度なログを避ける
class PerformantLogger {
private cache = new Map<string, any>();
logWithThrottle(key: string, message: string, delay: number = 1000): void {
const now = Date.now();
const lastLogged = this.cache.get(key);
if (!lastLogged || now - lastLogged > delay) {
console.log(message);
this.cache.set(key, now);
}
}
}
5. セキュリティへの配慮
// センシティブな情報をマスク
function logUserData(user: any): void {
const safeUser = {
...user,
password: "[REDACTED]",
creditCard: user.creditCard ? `****${user.creditCard.slice(-4)}` : undefined
};
console.log("ユーザーデータ:", safeUser);
}
まとめ
consoleオブジェクトは、TypeScript/JavaScript開発において最も基本的で重要なデバッグツールです。シンプルなconsole.logから、テーブル表示、グループ化、パフォーマンス測定まで、多様な機能を提供します。開発環境では積極的に活用し、本番環境では適切なログレベルとパフォーマンスを考慮した実装が重要です。より高度なロギング要件がある場合は、専用のロギングライブラリの使用を検討してください。