48
1 TypeScript 開發實戰 vs. JavaScript 物件導向觀念入門 多奇數位創意有限公司 技術總監 黃保翕 ( Will 保哥 ) 部落格:http://blog.miniasp.com/ 1

TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

1

TypeScript 開發實戰vs.

JavaScript 物件導向觀念入門

多奇數位創意有限公司

技術總監黃保翕 ( Will 保哥 )

部落格:http://blog.miniasp.com/

1

Will.Huang
戳記
Page 2: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

2

JAVASCRIPT 物件導向觀念入門

Object-Oriented JavaScript

Page 3: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

3

Douglas Crockford 大師說:

JavaScript:世界上被誤解最深的程式語言

http://javascript.crockford.com/javascript.html

Page 4: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

4

JavaScript 的型別概念

JavaScript 變數類型

String

Number

Boolean

Object

Array

Date

Null ?

Undefined

Page 5: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

5

JavaScript 的型別概念

JavaScript 型別分類

基礎型別 (Primitive Type)

string

number

boolean

undefined

null

物件型別 (Object Type)

object Function

Array

null ?

Page 6: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

6

JavaScript 的型別概念

JavaScript 是一種動態型別的語言

var x;var x = 5;var x = "John";

var carname="Volvo";var carname;

這種變數型別又稱「弱型別」 (Weak Type)

Page 7: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

7

JavaScript 的物件概念

JavaScript 物件,僅包含屬性與方法

var car = new Object();

屬性

car.name = "BMW";

方法

car.start();

"Everything" in JavaScript is an Object!

var txt = "Hello World";

txt.length

txt.indexOf('World');

Page 8: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

8

JavaScript 的物件概念

JavaScript 如何建立一個物件

var car = new Object();

car.name = "BMW";

car.start = function() {return true;

}

Object - JavaScript | MDN

Page 9: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

9

隨堂測驗 (1)

請回答以下問題:

var o1 = 'Hello World';

var o2 = new String('Hello World');

o1 == o2

o1 === o2

typeof o1

typeof o2

Page 10: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

10

隨堂測驗 (2)

以下陳述式是否會發生例外?

var car = 'Hello World';

car.name = "BMW";

car.start = function() {return true;

}

car.start();

Page 11: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

11

隨堂測驗 (3)

以下陳述式是否會發生例外?

var car = new String('Hello World');

car.name = "BMW";

car.start = function() {return true;

}

car.start();

Page 12: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

12

隨堂測驗 (4)

以下陳述式 txt.name 結果為何?

var car = 'Hello World';

String.prototype.name = "BMW";

String.prototype.start = function() {return true;

}

var txt = 'Will';

txt.name

Page 13: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

13

隨堂測驗 (5)

以下陳述式 txt.name 結果為何?

var car = new String('Hello World');

String.prototype.name = "BMW";

String.prototype.start = function() {return true;

}

var txt = 'Will';

txt.name

Page 14: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

14

JavaScript 的函數概念

JavaScript 如何建立一個函數 (1)

function HelloWorld(){

return "Hello World";}

Page 15: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

15

JavaScript 的函數概念

JavaScript 如何建立一個函數 (2)

var myFunc = function(){

return "Hello World";}

window.myFunc = function(){

return "Hello World";}

Function - JavaScript | MDN

Page 16: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

16

JavaScript 的函數概念

JavaScript 如何建立一個函數 (3)

var myFunc = new Function("return 'Hello World!!'");

Page 17: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

17

隨堂測驗 (6)

以下陳述式 txt.name 結果為何?

var o1 = function() {}

var o2 = new Function();

o1 == o2

o1 === o2

typeof o1

typeof o2

Zeros in JavaScripthttp://zero.milosz.ca/

Page 18: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

18

隨堂測驗 (7)

這到底在寫什麼? var A = function(foo)

{

var B = function() {

return A.prototype.constructor.apply(B, arguments);

};

B.prototype = A.prototype;

return B;

};

對不起,我又讓誤解加深了! >"<

Page 19: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

19

JavaScript 的類別概念

只有函數(Function)、沒有類別(Class )

如何宣告一個類類別 透過 Function 宣告一個 "Class"

var oo = function(){

this.a = 1;

this.b = '11';

this.c = function() { return 'ok'; }

}

宣告一個新物件

var oo2 = new oo();

oo2

Page 20: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

20

JavaScript 的類別概念

物件存取範圍? (Public / Private / Protected)

JavaScript 沒有 Class 只有 Function

Function 是一種 Object

所有 Object 屬性都是公開的 (public)

所以 JS 的類類別沒有 private 或 protected 存取範圍!!

Page 21: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

21

TYPESCRIPT 簡介

JavaScript for tools

Page 22: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

22

TYPESCRIPT 簡介

TypeScript = "靜態型別" + "動態型別"

用「靜態型別」語法來描述 JavaScript 的動態型別

TypeScript 語法涵蓋完整 JavaScript 語法

TypeScript = JavaScript + Class-based OOP 語法

支援 class (類別)、interface (介面)、module (模組)

TypeScript 最終將編譯成傳統的 JavaScript

語法相容於 ECMAScript 3 (ES3)

Any browser. Any host. Any OS. (含Node.js)

TypeScript 是一個工具語言!(適用於開發時期)

TypeScript 適合用來開發 Web 應用程式

靜態型別, 編譯器, 開發工具支援, 開源碼, 免費

Page 23: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

23

TypeScript 語法

語法 v.s. 關鍵字

所有 ES3 語法

module

class , extends

constructor

export

public, private

interface

implements

? (nullable)

Page 24: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

24

TYPESCRIPT 開發實戰

現有專案如何循序漸進的改用 TypeScript 開發 JavaScript 應用程式

Page 25: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

25

STEP 0. 變更副檔名

作業方式

將 *.js 直接改成 *.ts

修正建置動作: TypeScriptCompile

注意事項

Visual Studio 2012 的專案裡,至少要有先有一個 TypeScript 檔案,才能在手動修正副檔名時選擇 “TypeScriptCompile” 這個建置動作(Build Action)

Page 26: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

26

STEP 0. 變更副檔名

*.ts

標準 TypeScript 副檔名

*.d.ts

d is stand for declaration

此為 TypeScript 宣告檔專用的副檔名

用來預先宣告 TypeScript 開發環境中可能會用到的變數、函數與物件,物件的部分皆以interface 的方式宣告

Page 27: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

27

STEP 1. 型別註釋 (Type Annotations)

通用型別 所有型別都是 any 的子型別 (類似 .NET 的 Object 型別)

基本上 any 就是 JavaScript 可用的任意型別

基本型別

number

bool ( boolean1 )

string

null

undefined

物件型別

interface

module

class

支援 literal 型別

支援陣列型別2

1 新版 TypeScript v0.9 將 bool 型別改名為 boolean2 新版 TypeScript v0.9 將新增陣列泛型型別

Page 28: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

28

STEP 1. 型別註釋 (Type Annotations)

標示型別

變數宣告 (全域變數、類別變數、區域變數) 使用 : T 表示法

function 參數支援 optional types 運算子: ?

函式回傳值 支援型別推導

函式傳入參數

Page 29: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

29

比較用法:Literal 與 Interface 型別

Literal

Interface

Page 30: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

30

陣列型別的用法

Page 31: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

31

STEP 2. 加入宣告參考

加入方式

內建宣告參考: lib.d.ts

加入參考/// <reference path="jquery.d.ts"/>

參考資源

TypeScript Source Codehttp://typescript.codeplex.com/SourceControl/BrowseLatest

DefinitelyTypedhttps://github.com/borisyankov/DefinitelyTyped#readme

AngularJShttps://github.com/borisyankov/DefinitelyTyped/wiki/AngularJS-Definitions-Usage-Notes

Page 32: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

32

STEP 3. 重構 JS 程式碼

使用 class 定義類別

使用 interface 定義介面

使用 module 定義模組 (命名空間)

善用 TypeScript 工具支援

Page 33: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

33

使用 class 定義類別

可存取性限制

使用 public 與 private 關鍵字區分(僅限工具使用)

沒有 protected

繼承特性

僅支援單一繼承

衍生類別可以透過 super 呼叫父類別方法

其他

Parameter property declarations via constructor.

Page 34: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

34

TS 型別檢查 / JS 型別檢查

注意事項

類別中的私有變數,只會在 TS 編譯器中檢查

不過就算編譯器會報錯,JS 還是會順利產生!

如下範例:

class Test{

private member: any = "private member";}

alert(new Test().member);

Page 35: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

35

使用 interface 定義介面

特性

僅定義給工具使用,不會產生任何程式碼

屬「結構型別系統」

在 TypeScript 中,所有物件會依據 prototype 自動產生介面,因此「匿名型別」不用強制轉型,就能自動變成特定介面型別。

示範: structual_types.ts

支援多載函式,依據不同參數簽名(signature)

可定義於多個檔案,並可載入其他檔案

可實作多重介面

Page 36: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

36

使用 module 定義模組 (命名空間)

特性

類似 .NET 的命名空間

可有效避免變數名稱衝突

可有效定義模組裡類別的可見性 internal modules 預設

external modules 套上 export 關鍵字在類別上

Page 37: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

37

善用 TypeScript 工具支援

Visual Studio 2012

自動型別檢查 (Static type checking)

隱含強型別推演 (Strong type inference)

移至定義 (Go To Definition) ( F12 )

巡覽至 (Navigate To) ( Ctrl + , )

語法自動完成 / Intellisense ( Ctrl + j )

程式碼重構 (Code refactoring) ( F2 )

下載: TypeScript for Visual Studio 2012 ( v0.8.1.1 )

Monaco (線上版編輯器)

http://www.typescriptlang.org/Playground/

Page 38: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

38

TypeScript 的工具支援

TypeScript support for Sublime Text

http://www.interoperabilitybridges.com/media/155452/typescript_support_for_sublime_text.zip

TypeScript support for Emacs

http://www.interoperabilitybridges.com/media/155449/typescript_support_for_emacs.zip

TypeScript support for Vim

http://www.interoperabilitybridges.com/media/155446/typescript_support_for_vim.zip

Page 39: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

39

STEP 4. 偵錯方式

設計時期 (Design Time)

開發工具 即時型別檢查

即時 JavaScript 程式碼預覽 (Web Essentials 2012)

編譯器型別檢查 預設會將專案中所有 TypeScript 載入合併編譯

預先查出重複的型別定義(變數、類別、函式、…)

執行時期 (Run Time)

使用 Source Map 進行偵錯 ( Google Chrome ) 中斷點

單步偵錯

監看式

Page 40: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

40

Source Map 支援

問題

TypeScript-to-JavaScript → Debug JavaScript ??

解決方案

Source Map !!

自動對應目前的 JS 程式碼到 TS 程式碼

支援中斷點與逐步偵錯

Introduction to JavaScript Source Maps - HTML5 Rocks

http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/

Page 41: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

41

TypeScript 執行方式

透過工具事先轉換成 JavaScript

相容於 ECMAScript 3

可執行在各瀏覽器或 node.js

直接在 Browser 執行 TypeScript

typescript.jshttps://github.com/niutech/typescript-compile

live demo

Page 42: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

42

使用 TypeScript 的 5 大理由?

支援 ECMAScript 6 語法,執行在 ECMAScript 3 的瀏覽器上 (IE6+)ES 6 的 module, classES 3 的相容性: http://www.webdevout.net/browser-support-ecmascript

開源碼,採用 Apache 2.0 授權,可從 CodePlex 下載http://typescript.codeplex.com/

工具支援 (Visual Studio 2012, Vi, Emac, Sublime Text)支援 Intellisense、型別檢查、型別推導、程式碼重構、巡覽至、符號搜尋

與現有專案無縫整合8 → ∞

名家之著Anders Hejlsburg - C# 之父

Page 43: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

43

不用 TypeScript 的 6 大理由?

目前還在 Preview 階段TypeScript 0.8.3.1

還不斷發現 Bugs、工具支援也還在陸續開發(不過前景可期)

有限的支援與函式庫(需要時間解決)

目前版本尚未支援泛型(但 TypeScript 規格中已經有定義)

所有型別都是 nullable 型別

僅 Visual Studio 2012 與 Monaco web editor 支援較完整的工具特性

Page 44: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

44

結論

TypeScript 值得一試

現在就能用在專案上,沒有相容性問題

循序漸進的改善 JavaScript 程式碼品質

工欲善其事,必先利其器!Visual Studio 2012 是你的好朋友

Page 45: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

45

參考連結

TypeScript 官網 http://www.typescriptlang.org/

TypeScript 部落格 http://blogs.msdn.com/b/typescript/

TypeScript 原始碼下載 http://typescript.codeplex.com/SourceControl/BrowseLatest

TypeScript Language Specification http://go.microsoft.com/fwlink/?LinkId=267121

多奇技術分享會 - 微軟最新程式語言:TypeScript 介紹 http://www.youtube.com/watch?v=BicYCnjBYvc

Page 46: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

46

聯絡資訊

The Will Will Web記載著 Will 在網路世界的學習心得與技術分享

http://blog.miniasp.com/

Will 保哥的技術交流中心 (臉書粉絲專頁)

http://www.facebook.com/will.fans

★★★ Will 保哥的噗浪★★★

http://www.plurk.com/willh/invite

Page 47: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

47

Q & A

Page 48: TypeScript 開發實戰download.microsoft.com/download/C/6/0/C60E2BD0-8A7C-479F... · 2018-10-16 · All services from your imperative. 26 STEP 0. 變更副檔名 *.ts 標準TypeScript

All services from your imperative.

48

感謝各位