Edited at

TypeScript 言語仕様めも

More than 5 years have passed since last update.


目的

前回 Typescript を使う為の準備をしたので, 今回は Typescript の実装目的とその言語仕様をざっくり把握することを目的にざっくり調べてみました.


Typescript の実装目的

実装目的, もとい Javascript の問題を解決したいことがあり Typescript が実装されたと勝手に認識しています.


Javascript の問題を解決する為の Typescript

Coffeescript を始め AltJS の目的は Javascript をより強固に書けるようにすることだと思いますが, そのアプローチ方法は言語によって異なると考えています.


  • 問題: Javascript の動的型付け


    • 解決: コンパイル時に型チェックを行う静的型付けをし, より堅牢なプログラムの記述を可能にすること



  • 問題: 言語の自動度が高いことでコードの標準化が困難


    • 解決: クラスなどのモジュールを用意することでコードをある程度標準化できる



コードの標準化とは, いろいろなプログラミングスタイルで書けることでコードの書き方が属人化してしまうことを解決する, と認識しています. 言語の自由度が高ければ高いほどそうなってしまうのは仕方ないと思いますが, ある程度の基盤の上に書けるとよいですもんね:P


Typescript の型付け


用意されている型


  • プリミティブ型は Number、Boolean、String、Null、Undefined が使える

  • any という何を代入してもコンパイルエラーにならない型が用意されている


    • 静的型付けの利点を損なうので乱用しないようにとのこと



  • void という返り値が無いことを示す型がある.


配列型

配列を定義するときは型に [] をつけるそうです.


*.ts

var seasons : string[] = ['spring', 'summer', 'fall', 'winter'];  // ok

var num : number[] = [0, 1 ,2 ,3 ,4]; // ok
var num : number[] = [0, 1 ,2 ,3 ,'hello']; // コンパイルエラー


オブジェクト型

オブジェクトを定義する時は以下の様に, 名前: 型 のようにまず型の構造を宣言し, 必要ならば値を束縛させます.


*.ts

// オブジェクト型の変数を宣言

var foo: {
x: string;
y: number;
};

// 値を束縛させる
foo = {
x: 'TypeScript',
y: 123
};

// 出力
console.info(foo.x); // TypeScript


まとめ


  • Typescript の標準で用意されている型は Number、Boolean、String、Null、Undefined, any, void の 8 種類.

  • 配列型を定義する際には, 配列の因子の型に [] をつける

  • オブジェクト型を定義する際には, まずその型の構造を宣言し, 値を束縛させる.


変数宣言と代入

以下のサンプルは web で REPL があったのでこちらで実行して試せます:)

http://www.typescriptlang.org/Playground


*.ts

var hoge = 'hello';  // ok

var hoge2 = 'hello': string; // ok
var fuga: number = 10; // ok
var piyo: number = 'hoge'; // コンパイルエラー

var hogehoge: string = hoge; // ok
var fugafuga: number = hoge; // コンパイルエラー


まとめ


  • 型推論をサポート


    • 変数宣言時は型を指定できるが, 明らかに型が明瞭な場合は宣言が不要



  • 静的型付け


    • 型の同じ変数同士でしか代入が許可されていない



(注) 型推論についてはまだよく知りません.


関数定義

関数定義にはいくつかの方法があるようです.


*.ts

// ok

function square(n: number): number {
return n * n;
}

console.info(square(3)); // ok
console.info(square('hoge')); // コンパイルエラー


型推論してくれるので型を宣言しない以下のような記述でも ok


*.ts

// ok

function square(n) {
return n * n;
}

アロー関数式という構文での記述も可能だそうです. アロー関数式よく知りませんがラムダ記法に関係するとかなんとか...?


*.ts

// ok

var square = (n: number) => {
return n * n;
}

// ok
var square = (n) => {
return n * n;
}


まとめ


  • 関数を定義するには型を指定する, 型を指定しない, アロー関数式を使う.


モジュール定義

Typescript はクラスベースのオブジェクト指向の構文をサポートしているそうです. 色々用意されていますがインターフェイス, クラス, モジュールをちょこっと見てみます.


Interface

予め定義しておいたオブジェクト型リテラルに別名を定義する.


*.ts

// Person というオブジェクト型を定義する

interface Person{
name : string;
birthday : Date;
hello: ()=>void;
}

// person という変数を新たに定義し, Person オブジェクトの各要素に値を束縛させる.
var person : Person = {
name: 'John',
birthday: new Date('01/01/70 00:00:00'),
hello: function(){ console.log('Hello, my name is ' + this.name); }
};

// 出力
person.hello(); // Hello, my name is John



Class

クラスの定義は他のクラスベースの言語と似ています. class で宣言, extends でクラス継承, constructor でコンストラクタを定義します.


*.ts

// Bar というクラスを定義する.

class Bar {
constructor(private x: string) {
}
// private または public をつける. ない場合は public.
public greet(): string {
return 'Hello, ' + this.x;
}
}

var bar = new Bar('TypeScript');
console.info(bar()); // Hello, TypeScript



*.ts

module Greeting {

export class Hello {
constructor(private text : string) {
}
say() : void {
console.log(this.text);
}
}
}

var hello: Greeting.Hello = new Greeting.Hello('Hello, World!');
hello.say();



Module

モジュールには 2 種類あるそうです.


内部モジュール

内部モジュールはそれ自体は1つの名前空間を示すので, 以下の例で定義した x は別の値に束縛されています.


*.ts

var x: string = 'JavaScript';

module Foo {
var x: string;
x = 'TypeScript';
}


内部モジュールをその外側から参照するためには export を使います.


*.ts

module Foo {

export var x: string;
x = 'TypeScript';
}

var x: string = Foo.x;
console.info(x); // TypeScript


モジュール内の要素の別名を定義する import というインターフェイスもあるそうですが割愛.


外部モジュール

外部モジュールは, 別ファイルから参照できるようにするために用意されているインターフェイスです. CommonJS というライブラリと併用して使えるそうです.


log.ts

export function message(s: string) {

console.log(s);
}


main.ts

import log = module('log');

log.message('hello'); // hello

まとめ


  • クラスベースなオブジェクト指向スタイルの構文を取り入れいている

  • class, intarface, module などの Javascript だけでは実現がむずかしかったインターフェイスを提供している.


雑感

ざっくり Typescript 入門してみました. コンパイルの時点でエラーを吐いてくれたり, class や module を使えるのは便利そうだと思いました. Coffeescript に比べるとコードの記述量が多くなってしまいそうですが, 長く保守するようなプロダクトを実装する場合にはいいかもと思いました:D


References

http://phyzkit.net/typescript/

http://www.slideshare.net/kiyokura/type-script-21888663

http://www.typescriptlang.org/Playground

http://docs.solab.jp/typescript/module/internal/