JavaScriptプログラマーのためのTypeScript

TypeScriptは、JavaScriptと特殊な関係にあります。TypeScriptはJavaScriptのすべての機能を提供し、さらにその上にTypeScriptの型システムという追加のレイヤーを提供します。

たとえば、JavaScriptはstringnumberなどの言語プリミティブを提供しますが、これらを一貫して割り当てたかどうかはチェックしません。TypeScriptはチェックします。

つまり、既存の動作するJavaScriptコードはTypeScriptコードでもあります。TypeScriptの主な利点は、コード内の予期しない動作を強調表示し、バグの可能性を減らすことができることです。

このチュートリアルでは、TypeScriptの概要を簡単に説明し、その型システムに焦点を当てます。

型推論による型

TypeScriptはJavaScript言語を理解しており、多くの場合、型を自動的に生成します。たとえば、変数を作成し、特定の値を代入すると、TypeScriptはその値を型として使用します。

ts
let helloWorld = "Hello World";
let helloWorld: string
Try

JavaScriptの動作を理解することで、TypeScriptはJavaScriptコードを受け入れるが型を持つ型システムを構築できます。これにより、コードで型を明示的にするために追加の文字を追加する必要のない型システムが提供されます。上記例でhelloWorldstringであるとTypeScriptが認識する方法です。

Visual Studio CodeでJavaScriptを記述したことがあり、エディターの自動補完を利用したことがあるかもしれません。Visual Studio Codeは、JavaScriptをより簡単に操作できるようにするために、内部でTypeScriptを使用しています。

型の定義

JavaScriptでは、さまざまなデザインパターンを使用できます。ただし、一部のデザインパターンでは、型を自動的に推論するのが難しい場合があります(たとえば、動的プログラミングを使用するパターン)。これらのケースをカバーするために、TypeScriptはJavaScript言語の拡張機能をサポートしており、型がどうあるべきかをTypeScriptに指示する場所を提供します。

たとえば、name: stringid: numberを含む推論された型を持つオブジェクトを作成するには、次のように記述できます。

ts
const user = {
name: "Hayes",
id: 0,
};
Try

interface宣言を使用して、このオブジェクトの形状を明示的に記述できます。

ts
interface User {
name: string;
id: number;
}
Try

その後、変数宣言の後に: TypeNameのような構文を使用して、JavaScriptオブジェクトが新しいinterfaceの形状に準拠していることを宣言できます。

ts
const user: User = {
name: "Hayes",
id: 0,
};
Try

提供したインターフェイスと一致しないオブジェクトを提供すると、TypeScriptが警告します。

ts
interface User {
name: string;
id: number;
}
 
const user: User = {
username: "Hayes",
Type '{ username: string; id: number; }' is not assignable to type 'User'. Object literal may only specify known properties, and 'username' does not exist in type 'User'.2322Type '{ username: string; id: number; }' is not assignable to type 'User'. Object literal may only specify known properties, and 'username' does not exist in type 'User'.
id: 0,
};
Try

JavaScriptはクラスとオブジェクト指向プログラミングをサポートしているため、TypeScriptもサポートしています。クラスでインターフェイス宣言を使用できます。

ts
interface User {
name: string;
id: number;
}
 
class UserAccount {
name: string;
id: number;
 
constructor(name: string, id: number) {
this.name = name;
this.id = id;
}
}
 
const user: User = new UserAccount("Murphy", 1);
Try

インターフェイスを使用して、関数へのパラメーターと戻り値に注釈を付けることができます。

ts
function deleteUser(user: User) {
// ...
}
 
function getAdminUser(): User {
//...
}
Try

JavaScriptには、すでにbooleanbigintnullnumberstringsymbolundefinedという小さなプリミティブ型のセットが用意されており、インターフェイスで使用できます。TypeScriptは、このリストをany(すべてを許可)、unknown(この型を使用する人が型を宣言することを保証)、never(この型が発生する可能性はない)、およびvoidundefinedを返すか、戻り値がない関数)など、さらにいくつか追加して拡張します。

型を構築するための構文が2つあることがわかります:インターフェースと型interfaceを優先する必要があります。特定の機能が必要な場合はtypeを使用します。

型の構成

TypeScriptを使用すると、単純な型を組み合わせることで複雑な型を作成できます。これを行うには、ユニオンとジェネリックの2つの一般的な方法があります。

ユニオン型

ユニオン型を使うと、ある型が複数の型のいずれかであることを宣言できます。例えば、boolean 型を true または false のいずれかであると記述できます。

ts
type MyBool = true | false;
Try

注: 上記の MyBool にマウスカーソルを合わせると、boolean として分類されていることがわかります。これは構造型システムの特徴です。詳しくは後述します。

ユニオン型の一般的なユースケースは、値が許容される string または numberリテラルの集合を記述することです。

ts
type WindowStates = "open" | "closed" | "minimized";
type LockStates = "locked" | "unlocked";
type PositiveOddNumbersUnderTen = 1 | 3 | 5 | 7 | 9;
Try

ユニオン型は、異なる型を扱う方法も提供します。例えば、array または string を受け取る関数があるかもしれません。

ts
function getLength(obj: string | string[]) {
return obj.length;
}
Try

変数の型を調べるには、typeof を使用します。

述語
string typeof s === "string"
number typeof n === "number"
boolean typeof b === "boolean"
undefined typeof undefined === "undefined"
function typeof f === "function"
array Array.isArray(a)

例えば、文字列または配列のどちらが渡されたかによって異なる値を返す関数を作成できます。

ts
function wrapInArray(obj: string | string[]) {
if (typeof obj === "string") {
return [obj];
(parameter) obj: string
}
return obj;
}
Try

ジェネリクス

ジェネリクスは型に変数を提供します。一般的な例は配列です。ジェネリクスなしの配列には何でも含めることができます。ジェネリクス付きの配列は、配列に含まれる値を記述できます。

ts
type StringArray = Array<string>;
type NumberArray = Array<number>;
type ObjectWithNameArray = Array<{ name: string }>;

ジェネリクスを使用する独自の型を宣言できます。

ts
interface Backpack<Type> {
add: (obj: Type) => void;
get: () => Type;
}
 
// This line is a shortcut to tell TypeScript there is a
// constant called `backpack`, and to not worry about where it came from.
declare const backpack: Backpack<string>;
 
// object is a string, because we declared it above as the variable part of Backpack.
const object = backpack.get();
 
// Since the backpack variable is a string, you can't pass a number to the add function.
backpack.add(23);
Argument of type 'number' is not assignable to parameter of type 'string'.2345Argument of type 'number' is not assignable to parameter of type 'string'.
Try

構造型システム

TypeScript の中心的な原則の 1 つは、型チェックが値の持つ形状に焦点を当てていることです。これは「ダックタイピング」または「構造タイピング」と呼ばれることもあります。

構造型システムでは、2 つのオブジェクトが同じ形状を持つ場合、それらは同じ型であると見なされます。

ts
interface Point {
x: number;
y: number;
}
 
function logPoint(p: Point) {
console.log(`${p.x}, ${p.y}`);
}
 
// logs "12, 26"
const point = { x: 12, y: 26 };
logPoint(point);
Try

point 変数は、Point 型であるとは宣言されていません。ただし、TypeScript は型チェック時に point の形状と Point の形状を比較します。それらは同じ形状であるため、コードは合格します。

形状の一致には、オブジェクトのフィールドのサブセットが一致しているだけで十分です。

ts
const point3 = { x: 12, y: 26, z: 89 };
logPoint(point3); // logs "12, 26"
 
const rect = { x: 33, y: 3, width: 30, height: 80 };
logPoint(rect); // logs "33, 3"
 
const color = { hex: "#187ABF" };
logPoint(color);
Argument of type '{ hex: string; }' is not assignable to parameter of type 'Point'. Type '{ hex: string; }' is missing the following properties from type 'Point': x, y2345Argument of type '{ hex: string; }' is not assignable to parameter of type 'Point'. Type '{ hex: string; }' is missing the following properties from type 'Point': x, y
Try

クラスとオブジェクトが形状に適合する方法に違いはありません。

ts
class VirtualPoint {
x: number;
y: number;
 
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
 
const newVPoint = new VirtualPoint(13, 56);
logPoint(newVPoint); // logs "13, 56"
Try

オブジェクトまたはクラスに必須プロパティがすべて含まれていれば、実装の詳細に関係なく、TypeScript はそれらが一致するとみなします。

次のステップ

これは、日常的な TypeScript で使用される構文とツールの簡単な概要でした。ここから、以下のことができます。

TypeScript のドキュメントはオープンソースプロジェクトです。これらのページを改善するために、プルリクエストを送信してご協力ください ❤

このページの貢献者
OTOrta Therox (24)
DSDustin Stender (1)
MKMatt Kantor (1)
JCRJuan Carlos Ruiz (1)
IOIván Ovejero (1)
18+

最終更新日: 2024年3月21日