TypeScript
#11
TIOBE#37
PYPL#9
GitHub#6
RedMonk#6
IEEESpectrum#5
JetBrains#6
プログラミング言語
TypeScript
概要
TypeScriptは、Microsoftが開発したJavaScriptに静的型付けを追加したプログラミング言語です。
詳細
TypeScriptは2012年にMicrosoftによって開発された、JavaScriptのスーパーセットとして設計されたプログラミング言語です。JavaScriptのコードはそのままTypeScriptとして動作し、さらに静的型システム、インターフェース、ジェネリクス、デコレーターなどの機能を追加しています。TypeScriptコードはJavaScriptにトランスパイルされ、あらゆるJavaScript実行環境で動作します。大規模なアプリケーション開発における型安全性の向上、開発効率の向上、保守性の向上を目的としており、React、Angular、Vue.js、Node.jsプロジェクトで広く採用されています。
書き方の例
Hello World
// 基本的な出力
console.log("Hello, World!");
// 型注釈付きの変数
const message: string = "こんにちは、TypeScript!";
console.log(message);
// 関数の型注釈
function greet(name: string): string {
return `Hello, ${name}!`;
}
console.log(greet("TypeScript"));
基本的な型システム
// プリミティブ型
let age: number = 25;
let name: string = "太郎";
let isActive: boolean = true;
// 配列
let numbers: number[] = [1, 2, 3, 4, 5];
let fruits: Array<string> = ["apple", "banana", "orange"];
// オブジェクト型
let person: { name: string; age: number } = {
name: "田中太郎",
age: 30
};
// Union型(複数の型を許可)
let id: string | number = "abc123";
id = 123; // これも有効
// リテラル型
let status: "success" | "error" | "loading" = "success";
インターフェース
// インターフェースの定義
interface User {
id: number;
name: string;
email: string;
age?: number; // オプショナルプロパティ
}
// インターフェースの使用
const user: User = {
id: 1,
name: "山田花子",
email: "[email protected]"
};
// インターフェースの継承
interface Admin extends User {
role: string;
permissions: string[];
}
const admin: Admin = {
id: 2,
name: "管理者",
email: "[email protected]",
role: "administrator",
permissions: ["read", "write", "delete"]
};
関数の型付け
// 関数の型注釈
function add(a: number, b: number): number {
return a + b;
}
// アロー関数の型注釈
const multiply = (a: number, b: number): number => a * b;
// 関数型の変数
type MathOperation = (x: number, y: number) => number;
const divide: MathOperation = (a, b) => {
if (b === 0) {
throw new Error("Division by zero");
}
return a / b;
};
// オプション引数とデフォルト引数
function createUser(name: string, age?: number, role: string = "user"): User {
return {
id: Math.random(),
name,
email: `${name.toLowerCase()}@example.com`,
age
};
}
クラス
// クラスの定義
class Vehicle {
protected make: string;
protected model: string;
private _mileage: number = 0;
constructor(make: string, model: string) {
this.make = make;
this.model = model;
}
// ゲッター
get mileage(): number {
return this._mileage;
}
// メソッド
drive(distance: number): void {
this._mileage += distance;
console.log(`${distance}km運転しました。総走行距離: ${this._mileage}km`);
}
getInfo(): string {
return `${this.make} ${this.model}`;
}
}
// 継承
class Car extends Vehicle {
private doors: number;
constructor(make: string, model: string, doors: number) {
super(make, model);
this.doors = doors;
}
getInfo(): string {
return `${super.getInfo()} (${this.doors}ドア)`;
}
}
const myCar = new Car("トヨタ", "プリウス", 4);
console.log(myCar.getInfo());
ジェネリクス
// ジェネリック関数
function identity<T>(arg: T): T {
return arg;
}
const stringResult = identity<string>("hello");
const numberResult = identity<number>(42);
// ジェネリックインターフェース
interface Container<T> {
value: T;
getValue(): T;
}
class Box<T> implements Container<T> {
constructor(public value: T) {}
getValue(): T {
return this.value;
}
}
const stringBox = new Box<string>("TypeScript");
const numberBox = new Box<number>(123);
// 制約付きジェネリクス
interface Lengthwise {
length: number;
}
function logLength<T extends Lengthwise>(arg: T): T {
console.log(`長さ: ${arg.length}`);
return arg;
}
logLength("文字列"); // OK
logLength([1, 2, 3]); // OK
// logLength(123); // エラー: numberにはlengthプロパティがない
型エイリアスと型ガード
// 型エイリアス
type StringOrNumber = string | number;
type UserRole = "admin" | "user" | "guest";
// 型ガード
function isString(value: StringOrNumber): value is string {
return typeof value === "string";
}
function processValue(value: StringOrNumber): void {
if (isString(value)) {
// この中ではvalueはstring型として扱われる
console.log(value.toUpperCase());
} else {
// この中ではvalueはnumber型として扱われる
console.log(value.toFixed(2));
}
}
// Discriminated Union
interface Circle {
kind: "circle";
radius: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
type Shape = Circle | Rectangle;
function calculateArea(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "rectangle":
return shape.width * shape.height;
default:
// 網羅性チェック
const _exhaustiveCheck: never = shape;
return _exhaustiveCheck;
}
}
デコレーター(実験的機能)
// クラスデコレーター
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
// メソッドデコレーター
function log(target: any, propertyName: string, descriptor: PropertyDescriptor) {
const method = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`${propertyName}メソッドが呼び出されました`);
return method.apply(this, args);
};
}
@sealed
class ExampleClass {
@log
greet(name: string): string {
return `Hello, ${name}!`;
}
}
バージョン
バージョン | リリース日 | 主な新機能 |
---|---|---|
TypeScript 5.5 | 2024-06 | Inferred Type Predicates, Control Flow Narrowing |
TypeScript 5.4 | 2024-03 | NoInfer Utility Type, Object.groupBy support |
TypeScript 5.3 | 2023-11 | Import Attributes, Switch (true) Narrowing |
TypeScript 5.2 | 2023-08 | using Declarations and Explicit Resource Management |
TypeScript 5.1 | 2023-06 | Unrelated Types in Union, JSDoc @param and @returns |
TypeScript 5.0 | 2023-03 | Decorators, const Type Parameters |
TypeScript 4.9 | 2022-11 | satisfies Operator, Auto-Accessors |
参考ページ
公式ドキュメント
- TypeScript公式サイト - 公式サイト
- TypeScript Handbook - 公式ドキュメント
- TypeScript Playground - ブラウザ上でTypeScriptを試せる環境
学習リソース
- TypeScript Deep Dive - TypeScript詳細ガイド
- TypeScript Tutorial - TypeScriptチュートリアル
- TypeScript in 5 minutes - 5分でわかるTypeScript
開発ツール
- Visual Studio Code - TypeScript標準対応エディタ
- DefinitelyTyped - 型定義ファイルリポジトリ
- ts-node - Node.js用TypeScript実行環境