TypeScriptを5分で試す

これまでのお話

 TypeScriptだけを使いたいので、お試し用のプロジェクトを作ったところまでやりました。

TypeScript Tooling in 5 minutes !

 TypeScriptのインストールが終わったら、公式サイトの「TypeScript Tooling in 5 minutes」をやってみます。じっくり英文読むのも良いですが、私はやってみて、ようやく理解するタイプの人間なので…。

コンパイル & 使ってみる

 プロジェクトフォルダ直下に、「greeter.ts」ファイルを作成し、サイトのソースコードをコピペします。ここでは前回作成した、TSTestフォルダ内に作成しています。

// greeter.ts

function greeter(person) {
 return "Hello, " + person;
}

let user = "Jane User";

document.body.textContent = greeter(user);

 これを保存したら、コンパイルします。ローカルインストールしているので、フォルダ指定して実行します。

TSTest $ ./node_modules/.bin/tsc greeter.ts

 greeter.ts と同じ場所にgreeter.jsが作成されます。※コンパイラオプションファイルで設定すれば、別の場所に出力できるようです。

スクリーンショット 2020-05-09 13.42.06

 さてさて、Javascriptにしたからには、使ってみましょう。greeter.htmlを作成し、scriptタグでgreeter.jsを指定します。

<!DOCTYPE html>
<html>
 <head>
   <title>TypeScript Greeter</title>
 </head>
 <body>
   <script src="greeter.js"></script>
 </body>
</html>

 Webブラウザでgreeter.htmlを実行すると、greeter.jsの結果が表示されています。

スクリーンショット 2020-05-09 17.57.01

型の指定と、型違いのエラーを確認する

 次にTypeScriptの特徴である型指定を試してみます。公式サイトの見本に従って、greeter関数の引数personにstring型を指定します。さらに、変数userを数値の配列に書き換えます。

// greeter.ts
function greeter(person: string) {
   return "Hello, " + person;
 }
 
 let user = [0, 1, 2];
 
document.body.textContent = greeter(user);

 すると、関数の引数と、実際に渡される変数の型が違う為、コンパイルする前に、以下のようなエラーになります。

型 'number[]' の引数を型 'string' のパラメーターに割り当てることはできません。

スクリーンショット 2020-05-09 14.36.07

 VSCを使っておらず、ターミナル上で無理矢理コンパイルしても、同様にエラーとなります。

スクリーンショット 2020-05-09 15.26.21

Interfaceを使ってみる

 インタフェースも作成できます。

// greeter.ts

interface Person {
 firstName: string;
 lastName: string;
}

function greeter(person: Person) {
 return "Hello, " + person.firstName + " " + person.lastName;
}

let user = { firstName: "Jane", lastName: "User" };

document.body.textContent = greeter(user);

 この例では、Personというインタフェースが作成されており、そのインタフェース内で、firstName、lastNameともにstring型で作成することが決められています。その為、lastNameの型をnumberに変更してみると「約束されてる型と違うやんけ!!」とエラーとなります。

スクリーンショット 2020-05-09 16.08.23

 これにより、何がメリットとなるのか……。実は私、TypeScriptとか関係なく、あまりインタフェースのメリットを理解できていません。同じような疑問についての話があったので、以下にリンクを配置しておきます(投げやり)。


Classを試す - その1

 今度は、オブジェクト指向おなじみのクラスです。公式サイトの例は、色々すっ飛ばしていて、理解するのにちょっと時間かかってしまったので、もう少しシンプルなものに書き換えてあります。

// greeter.ts

class Student {
   fullName: string;

   constructor(
      firstName: string,
      middleInitial: string,
      lastName: string
   )
   {
     this.fullName = firstName + " " + middleInitial + " " + lastName;
   }
  }
     
  function greeter(student: Student) {
   return "Hello, " + student.fullName;
  }
  
  let student = new Student("Jane", "M.", "User");
  
  document.body.textContent = greeter(student);

 変数studentにStudentクラスのインスタンスを格納する際に、3つの引数を渡しています。それらは、コンストラクタで結合され、this.fullNameに代入されます。これを最終的に出力するわけですね。

スクリーンショット 2020-05-09 17.55.51

Classを試す - その2

 さて、ここで少し、公式サイトの記述に近づけます。

// greeter.ts

class Student {
   
   fullName: string;
  
   constructor(
      public firstName: string,
      public middleInitial: string,
      public lastName: string
   )
   {
     this.fullName = firstName + " " + middleInitial + " " + lastName;
   }
  }
     
  function greeter(student: Student) {
   return "Hello, " + student.fullName;
  }
  
  let student = new Student("Jane", "M.", "User");
  
  document.body.textContent = greeter(student);

 コンストラクタの引数に、publicをつけました。これによりどうなるかは、以下公式サイトの引用の通りです。

Also of note, the use of public on arguments to the constructor is a shorthand that allows us to automatically create properties with that name.

また、コンストラクターの引数でpublicを使用すると、その名前のプロパティを自動的に作成できるようになります。

 つまりどういうことだってばよ…ということで、コンパイルして生成されたjavascriptを見てみましょう。

↓ publicが付いていない場合のコンパイル結果

// greeter.ts
var Student = /** @class */ (function () {
   function Student(firstName, middleInitial, lastName) {
       this.fullName = firstName + " " + middleInitial + " " + lastName;
   }
   return Student;
}());
function greeter(student) {
   return "Hello, " + student.fullName;
}
var student = new Student("Jane", "M.", "User");
document.body.textContent = greeter(student);

↓ publicが付いている場合のコンパイル結果

// greeter.ts
var Student = /** @class */ (function () {
   function Student(firstName, middleInitial, lastName) {
       this.firstName = firstName;         // 追加された
       this.middleInitial = middleInitial; // 追加された
       this.lastName = lastName;           // 追加された
       this.fullName = firstName + " " + middleInitial + " " + lastName;
   }
   return Student;
}());
function greeter(student) {
   return "Hello, " + student.fullName;
}
var student = new Student("Jane", "M.", "User");
document.body.textContent = greeter(student);

関数Studentの中に「this.firstName = firstName」などの記述が増えています。

Classを試す - その3

ここでようやく、公式サイトの例を引っ張り出してきます。

// greeter.ts

class Student {
   fullName: string;
   constructor(
       public firstName: string,
       public middleInitial: string,
       public lastName: string
       ) {
       this.fullName = firstName + " " + middleInitial + " " + lastName;
       }
}

interface Person {
   firstName: string;
   lastName: string;
}

function greeter(person: Person) {
   return "Hello, " + person.firstName + " " + person.lastName;
}

let user = new Student("Jane", "M.", "User");

document.body.textContent = greeter(user);

 注目すべきは、関数greeterの引数の型が、インタフェースのPersonになっていることです。これにより、引数に渡されたStudentクラスのfirstName、lastNameの値が、Personの同名のプロパティに代入されることとなります。

以上!!

 さて、まだまだスタートラインに立っただけの状態ですが、とりあえずざっとやってみました。他にもReactやVue、Webpackなどと一緒に使うことでもっと活用出来るようですが、まずはExampleを進めて理解するのも良いのかなと思います。

では。

この記事が気に入ったらサポートをしてみませんか?