▶ 技術めも
TypeScript
class User {
// TODO
}
console.log("Hello");
------------------------------------------------------------
// 列挙型
// わかりやすく定数を表現
enum Signal {
Red = 0,
Blue = 1,
Yellow = 2
}
enum Signal {
Red, // 0
Blue = 3,
Yellow // 4
}
// 同じ列挙型はマージされる
var result: Signal; // 宣言
if (result === Signal.Yellow) { ... }
if (result === Signal['Yellow']) { ... }
console.log(Signal[2]); // Yellow
------------------------------------------------------------
// 静的型付け
// void
function add(a: number, b: number): number {
return a + b;
}
// b がオプションの場合
function add(a: number, b?: number): number {
if (b) {
return a + b;
} else {
return a + a;
}
}
// b に初期値を設定
function add(a: number, b: number = 10): number {
return a + b;
}
------------------------------------------------------------
// 関数
var add = function(a: number, b: number): number {
return a + b;
}
var add = (a: number, b: number): number => {
return a + b;
}
// 最後に評価された値が return になる
var add = (a: number, b: number): number => a + b
------------------------------------------------------------
// 関数のオーバーロード
function add(a: number, b: number): number; // シグネチャ
function add(a: string, b: string): string;
function add(a: any, b: any) {
if (typeof a === "string" && typeof b === "string") {
return a + " " + b;
}
return a + b;
}
------------------------------------------------------------
// クラス
// アクセス修飾子 デフォルト public, private, protected
class User {
name: string;
constractor(name: string) {
this.name = name;
}
saiHi(): void { // function は不要
console.log("Hi I am " + this.name)
}
}
var tom = new User("Tom");
console.log(tom.name);
tom.sayHi();
------------------------------------------------------------
// Class
class User {
public name: string;
constractor(public name: string) { // クラス変数に保持
}
public saiHi(): void { // function は不要
console.log("Hi I am " + this.name)
}
}
------------------------------------------------------------
// getter, setter
// コンパイラーでオプション必要 「-t ES5」
constractor(private _name: string) {
}
get name() {
return this.name;
}
set name(newName: string) {
this._name = newName;
}
console.log(tom.name);
tom.name("papa");
console.log(tom.name);
------------------------------------------------------------
// クラスの継承
class AdminUser extends User {
private _age: number;
constractor(_name: string, _age: number) {
super(_name);
this._age = _age;
}
public sayHi(): void { // メソッド オーバーライド
console.log("my age: " + this._age);
super.sayHi();
}
}
------------------------------------------------------------
// 変数、メソッド → そのクラスの「メンバ」と呼ぶ
// 静的メンバ
class User {
cnstractor(name: string) {
this.name = name;
User.count++; // ★
}
static count: number = 0; // ★
static showDescription(): void { // ☆
console.log("this is description");
}
}
var tom = new User("Tom")
var bob = new User("Bob")
console.log(User.count); // ★
User.showDescription(); // ☆
------------------------------------------------------------
// Intardace
finction getTotal(result: {a: number, b: number}) { // 直書き
return result.a + result.b;
}
var result = {a: 32, b: 58};
console.log(getTotal(result));
------------------------------
interface Result {
a: number,
b: number
}
finction getTotal(result: Result) { // インターフェイス
return result.a + result.b;
}
var result = {a: 32, b: 58};
console.log(getTotal(result));
------------------------------
// 構造的部分型
// ある型のプロパティさえ持っていれば、その型として扱う
interface Result {
a: number,
b: number
}
finction getTotal(result: Result) { // インターフェイス
return result.a + result.b;
}
var result = {a: 32, b: 58, c: "Hello"}; // ★ C が余計にあるけど問題なく処理される
console.log(getTotal(result));
------------------------------------------------------------
// インターフェイスは複数のインターフェイスから継承できる
interface FinalResult extends SpringResult, FallResults {
final: number;
}
------------------------------------------------------------
// Interface -> Class
interface GameUser {
score: number;
showUser(): void;
}
class User implements GameUser {
sore: number =0; // 必須
howScore(): void { // 必須
……
}
------------------------------------------------------------
// Genrtics ジェネリック
function getStringArray(value: string): string[] {
return [value, value, value]
}
function getNumberArray(value: number): number[] {
return [value, value, value]
}
↓
function getArray<T>(value: T): return T[] {
return [value, value, value]
}
console.log(getArray<number>(3));
console.log(getArray<string>("Hello"));
------------------------------------------------------------
// ジェネリック Class
class MyData<T> {
constractor(public value: T) {}
getArray(): T[] {
return [this.value, this.value, this.value];
}
}
var v1 = new MyData<string>("Hello");
console.log(v1.getArray());
var v2 = new MyData<number>(234);
console.log(v2.getArray());
------------------------------------------------------------
// ジェネリックに成約
interface Result {
a: number,
b: number
}
class MyData<T extends Result> { // 型は何でもいいが a, b 必須
constractor(public value: T) {}
getArray(): T[] {
return [this.value, this.value, this.value];
}
}
var v3 = new MyData<Result>({a: 32, b: 16}); // a, b さえ持ってればいい(構造的部分型)
console.log(v3.getArray());
------------------------------------------------------------
// 内部モジュール
module UserModule {
export var name = "taguchi"; // export 外部に対して公開する
export module AdressModule {
var zip = "111-111";
}
}
console.log(UserModule.name);
console.log(UserModule.AdressModule.zip);
import addr = UserModule.AdressModule; // 別名で定義
console.log(addr.zip);
// ------------------------------
// 別ファイル user.ts
/// <reference path="./user.ts" />
console.log(UserModule.name);
console.log(UserModule.AdressModule.zip);
→ js が2つできてしまうので、--out オプション
$ tsc main.js --out all.js
------------------------------------------------------------
// 外部モジュール
// Node - CommonJS
// RequireJS - AMD
// 1ファイル1モジュール
------------------------------
user_commonjs.ts
------------------------------
export var name = "taguchi";
------------------------------
import User = require("./user_common_js"); // 拡張子不要
console.log(User.name);
$ tsc main.ts -m commonjs
→ user_commonjs.js が作成
------------------------------
user_amd.ts
------------------------------
export var name = "taguchi";
------------------------------
import User = require("./user_amd"); // 拡張子不要
console.log(User.name);
$ tsc main.ts -m amd
→ user_amd.js が作成
http://dotinstall.com/lessons/basic_typescript
- マイクロソフト
- TypeScript -> JavaScript
- 静的な型付け
- クラスベースのオブジェクト指向
http://www.typescriptlang.org/
インストール
sudo npm install -g typescript
- main.ts
class User {
}
console.log("hello world");
tsc main.ts
→ main.js
node main.js
変数の静的型付け <-> 動的型付け(type script)
// TypeScript
var x: number = 10;
x = "hello";
型
/*
number
string
boolean
any
*/
var i: number;
var i: number = 10;
var i = 10; // i: number
var x; // var x: any
x = 10;
x = "hello";
var results: number[];
results = [10, 5, 3];
列挙型(わかり易く定数を表現)
/*
enum Signal {
Red = 0,
Blue = 1,
Yellow = 2
}
*/
enum Signal {
Red, // 0
Blue = 3,
Yellow // 4
}
enum Signal {
Green = 5 // マージされる
}
var result: Signal;
// if (result === Signal.Yellow) { ... }
// if (result === Signal['Yellow']) { ... }
// console.log(Signal[2]); // Yellow
// console.log(Signal[3]); // Blue
console.log(Signal.Green); // 5
関数 - 静的型付け
- 返り値がない void
- 引数がオプション b?
function add(a: number, b: number): number {
return a + b;
}
function add(a: number, b?: number): number {
// b が無かった場合
if (b) {
return a + b;
} else {
return a + a;
}
}
function add(a: number, b: number = 10): number {
return a + b;
}
// console.log(add(5, 3));
// console.log(add(5, "hello"));
console.log(add(5, 3));
console.log(add(5));
関数式
var add = function(a: number, b: number): number {
return a + b;
}
// アロー関数式( => )
var add = (a: number, b: number): number => {
return a + b;
}
// リターンも省略可能
var add = (a: number, b: number): number => a + b;
console.log(add(5, 3));
関数のオーバーロード
function add(a: number, b: number): number; // シグネチャ(関数の引数と返り値のコンビ)
function add(a: string, b: string): string;
function add(a: any, b: any): any {
if (typeof a === "string" && typeof b === "string") {
return a + " " + b;
}
return a + b;
}
// console.log(add(5, 3)); // 8
// console.log(add("hello", "world")); // hello world
console.log(add("hello", 3));
クラス
// public, protected, private アクセス修飾子
class User {
public name: string;
constructor(name: string) {
this.name = name;
}
↓
// コンストラクタでメンバ変数定義&設定
constructor(public name: string) {
}
public sayHi(): void {
console.log("hi! i am " + this.name);
}
}
var tom = new User("Tom");
console.log(tom.name);
tom.sayHi();
GETTER, SETTER
class User {
// private に変更
constructor(private _name: string) {
}
public sayHi(): void {
console.log("hi! i am " + this._name);
}
// GETTER(tom.name で取得) - ECMA5の機能
get name() {
return this._name;
}
// SETTER(tom.name = "TOM"; で設定)- ECMA5の機能
set name(newValue: string) {
this._name = newValue;
}
}
var tom = new User("Tom");
console.log(tom.name);
tom.name = "TOM";
console.log(tom.name);
tom.sayHi();
ECMA5 コンパイル
tsc main.ts -t ES5
クラス継承
// public, protected, private
class User {
constructor(protected _name: string) {
}
public sayHi(): void {
console.log("hi! i am " + this._name);
}
}
// extends で継承
class AdminUser extends User {
private _age: number;
constructor(_name: string, _age: number) {
super(_name);
this._age = _age;
}
public sayHi(): void {
console.log("my age: " + this._age);
console.log("my name: " + this._name);
// 親クラスの SayHi 実行
super.sayHi();
}
}
var bob = new AdminUser("Bob", 23);
bob.sayHi();
静的メンバ static
- メンバ:そのクラスの変数やメソッド
- インスタンスではなく、class に保持されるメンバ
class User {
name: string;
constructor(name: string) {
this.name = name;
User.count++;
}
sayHi(): void {
console.log("hi! i am " + this.name);
}
static count: number = 0;
static showDescription(): void {
console.log("this class is about users");
}
}
var tom = new User("Tom");
var bob = new User("Bob");
console.log(User.count);
User.showDescription();
Interface
オブジェクトの型に名前をつけるもの
構造的部分型
ある型のプロパティを持っていれさえすれば、その「型」としてみなす
interface Result {
a: number;
b: number;
}
// 変数の型付け
function getTotal(result: {a: number, b: number}) {
↓
function getTotal(result: Result) {
return result.a + result.b;
}
var result = {
a: 32,
b: 58,
c: "hello" // 構造的部分型
};
console.log(getTotal(result));
Interface
複数インターフェイスを継承可能
interface SpringResult {
a: number;
}
interface FallResult {
b: number;
}
interface FinalResult extends SpringResult, FallResult {
final: number;
// final?: number; // オプション指定
}
function getTotal(result: FinalResult) {
// オプションの確認
if (result.final) {
return result.a + result.b + result.final;
} else {
return result.a + result.b;
}
}
var result = {
a: 32,
b: 58
};
console.log(getTotal(result));
インターフェイスの実装
Interface と Class を紐付ける
interface GameUser {
score: number;
showScore(): void;
}
class User implements GameUser {
name: string;
score: number = 0; // 実装しないtぽ行けない
constructor(name: string) {
this.name = name;
}
sayHi(): void {
console.log("hi! i am " + this.name);
}
showScore(): void { // 実装しないtぽ行けない
console.log("score " + this.score);
}
}
ジェネリクス
Generics: 抽象化されたデータ型
function getStringArray(value: string): string[] {
return [value, value, value];
}
function getNumberArray(value: number): number[] {
return [value, value, value];
}
↓
function getArray<T>(value: T): T[] {
return [value, value, value];
}
console.log(getArray<number>(3)); // 呼び出し側で「型」を指定
console.log(getArray<string>("hello")); // 呼び出し側で「型」を指定
ジェネリクスに制約を付与
class MyData<T> {
constructor(public value: T) {}
getArray(): T[] {
return [this.value, this.value, this.value];
}
}
var v1 = new MyData<string>("hello");
console.log(v1.getArray());
var v2 = new MyData<number>(234);
console.log(v2.getArray());
interface Result {
a: number;
b: number;
}
class MyData<T extends Result> {
constructor(public value: T) {}
getArray(): T[] {
return [this.value, this.value, this.value];
}
}
var v3 = new MyData<Result>({a: 32, b: 16});
console.log(v3.getArray());
interface Result {
a: number;
b: number;
}
interface FinalResult {
a: number;
b: number;
c: string;
}
class MyData<T extends Result> {
constructor(public value: T) {}
getArray(): T[] {
return [this.value, this.value, this.value];
}
}
// a, b を持っていればOKなので、FinalResult もOK(構造的部分型)
var v4 = new MyData<FinalResult>({a: 32, b: 16, c: "hello"});
console.log(v4.getArray());
内部モジュール
module UserModule {
export var name = "taguchi"; // export:外部に対して公開する
export module AddressModule {
export var zip = "111-1111";
}
}
console.log(UserModule.name);
console.log(UserModule.AddressModule.zip);
// 短い名前に出来る
import addr = UserModule.AddressModule;
console.log(addr.zip);
main.ts
// スラッシュ3つでモジュール読み込み
/// <reference path="./user.ts" />
console.log(UserModule.name);
import addr = UserModule.AddressModule;
console.log(addr.zip);
user.ts
module UserModule {
export var name = "taguchi";
export module AddressModule {
export var zip = "111-1111";
}
}
コンパイル
tsc main.js --out all.js
外部モジュールを使ってみよう
- Node - CommonJS
- RequireJS - AMD
1ファイルに1モジュール
→ よって module定義 はいらない
user_commonjs.ts、user_amd.ts
exports.name = "taguchi";
CommonJS 形式
import User = require("./user_commonjs");
console.log(User.name);
コンパイル
tsc main.ts -m commonjs // CommonJS形式
AMD 形式
import User = require("./user_amd");
console.log(User.name);
コンパイル (AND形式)
tsc main.ts -m amd // AND形式