公式サイトを参考にTypeScriptを初めてさわってみた感想
コンパイル時に型でエラーが出せるのがいいなと思いました。今回は公式サイトのチュートリアルから手をつけました。
setup
npm install -g typescript
cd src
tsc -w * --outDir ../dist
interfaceがコンパイル後のソースコードに影響を与えない
let num: number = 1
という書き方もですが、interface
を使った場合もコンパイル後のソースコードに影響を与えません。: number
やinterface
の部分は取り除かれます。コンパイル時だけ使われるようです。そのため、型だけ使うならいつでもTypeScriptを離れることができますね。
interface
はとりあえずこういうプロパティ名を管理したいという下書きみたいに使えるのが良いですね。options = {}
と1つの引数で複数のオプションを渡せるようにしていましたが、これだと何のオプションが選択可能かわかりずらいです。これをinterface
として定義しておけば見通しが良くなると思います。
class Student {
fullName: string;
constructor(public firstName, public middleInitial, public lastName) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}
interface Person {
firstName: string;
lastName: string;
}
function greeter(person: Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
var user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);
var Student = (function () {
function Student(firstName, middleInitial, lastName) {
this.firstName = firstName;
this.middleInitial = middleInitial;
this.lastName = lastName;
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
return Student;
}());
function greeter(person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
var user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);
定数をまとめるならenumを使う
フラグ管理に重宝しそうです。定数を管理するためのinterface
という感じがしました。enum
にはインデックスでもラベルでもアクセスできるのが凄いです。var current = status.poison
とラベルでセットすることもできますし、rate[0]
で"悪い"
を取得したりと段階に対応したラベルを取得とかに使おうかな。
enum Color {Red, Green, Blue};
let c: Color = Color.Green;
console.log(Color); // Object {0: "Red", 1: "Green", 2: "Blue", Red: 0, Green: 1, Blue: 2}
console.log(Color[0]); // Red
console.log(Color.Red); // 0
console.log(Color['Red']); // 0
Color[Color["Red"] = 0] = "Red";
は、Color["Red"] = 0
で0
が評価値になるので最終的にはColor[0] = "Red";
という形になります。1行で2つのプロパティを作るのは面白い書き方です。
即時関数の引数(Color || (Color = {})
ですが、Color ||
としていることで、Color
を拡張できるようにしていますね。もう一度enum Color
と書けばプロパティを追加できます。
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
;
var c = Color.Green;
console.log(Color); // Object {0: "Red", 1: "Green", 2: "Blue", Red: 0, Green: 1, Blue: 2}
console.log(Color[0]); // Red
console.log(Color.Red); // 0
console.log(Color['Red']); // 0
voidはundefinedとnullを表す型
関数の戻り値の型にvoid
を使うと、戻り値がないことを示すとありました。JavaScriptはreturn
を明示的に書かないとundefined
を返します。つまり、void
でundefined
を返すかをチェックしています。これは関数だけでなく、変数の型にも使えますが使い道は思いつきませんでした。
function warnUser(): void {
console.log("This is my warning message");
}
let unusable: void = undefined;
unusable = null;
anyとキャストの使い道がわからない
型にobject
ではなく、any
を指定すると何のメソッドを指定しても警告が出ません。何でも許容するということです。any
型を他の型にするには<string>myVal
のようにキャストするのですが、しなくても警告なしで代入できました。キャストさせてメソッド呼び出しで警告を出すようにするのかな。イマイチ使い方がわかりませんでした。
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
内側と外側のスコープで同名の変数は、同スコープに持ってきも別扱いになる。
サンプルで面白いコードがありました。よく考えれば複数のDOMにループでイベントハンドラをセットするのと同じです。
function outer() {
var a = 1;
a = 2;
var b = inner();
a = 3;
return b;
function inner() {
return a;
}
}
console.log("outer() : " + outer()); // 2
functionを書かずに済むlet
let
を使うと関数スコープからブロックスコープに変更することができます。クロージャのために関数を書かなくて済みます。もう常にvar
ではなく、let
を使うようにすれば良い気がしました。
for (let i =0; i < 10; i++) {
setTimeout(function() {console.log(i);}, 100 * i);
}
var _loop_1 = function(i) {
setTimeout(function () { console.log(i); }, 100 * i);
};
for (var i = 0; i < 10; i++) {
_loop_1(i);
}