Egret TypeScript基本寫法學習文件
阿新 • • 發佈:2019-01-08
基本型別
基礎型別只有這麼幾種,與AS3對比
TypeScript ActionScript3
number Number
string String
boolean(0.8以前為bool) Boolean
any *
undefined undefined
null null
任意型別:
ActionScript3 :
var anyType : * = ...;
TypeScript:
var anyType : any = ...;
變數修飾符:
TS類似AS3 但不用寫”var” , 沒有protected (未來也許會新增),預設為public。
ActionScript3 :
private var str: String = "abc";
public var num: Number = 123;
var num2 :Number = 456;
static var bo: Boolean = true;
public var createTime: String;
TypeScript:
private str: string = "abc"; // private property
public num: number = 123; // public property
num2 :number = 456; // 不寫預設也為public
static bo: boolean = true; // static
public createTime: string; //createTime 型別為string,值為 undefined
變數型別轉換:
ActionScript3 :
var str:String = "abc";
var strNum:Number = Number(str);
var strNum:Number = str as Number;
TypeScript :
var str : string = "abc";
var strNum: number = <number> str; //編譯報錯 Cannot convert 'string' to 'number'
發現使用any型別會編譯通過:
var str2 :any = "abc"; //any型別
var strNum2 :number = <number> str2; //通過
strNum2 += 5; // abc5
用 instanceof 判斷型別
// instanceof
function CalculateArea(shape : Shape) : number {
if (shape instanceof Square) {
return (<Square>shape).x * (<Square>shape).y;
}
if (shape instanceof Ellipse) {
return (<Ellipse>shape).r1 * (<Ellipse>shape).r2 * Math.PI;
}
if (shape instanceof Triangle) {
return 0.5 * (<Triangle>shape).x * (<Triangle>shape).y;
}
throw new TypeError("Unsupported type!");
}
陣列
Typescript陣列的寫法比AS3漂亮很多
ActionScript3 :
var arr:Array = [1,2,3,"a","b","c"]; // 任意型別陣列
var strArray:Vector.<String> = Vector.<String>(["a", "b", "c"]); //固定型別陣列
TypeScript :
var arr: any[] = new Array(); // 任意型別陣列
var strArr: string[] = ["a", "b", "c" ]; //固定型別陣列
二維陣列
var array2d: string[][] = [
["a", "b", "c"],
["x", "y", "z"]
];
// or
var array2d: string[][] = new Array();
array2d.push(["a", "b", "c"]);
array2d.push(["x", "y", "z"]);
Object Types
當AS3呼叫這樣一個函式時,會有下面一個問題。
ActionScript3 :
function CalculateArea ( rect : Object ):Number
{
return rect.width * rect.height;
}
此時編譯器並不知道rect這個Object裡到底有沒有width和height,只能等到runtime時才會知道。
TypeScript 引入Object Types解決這一問題,可以指定Object引數的具體內容,相當於讓Object引數實現了interface
function CalculateArea(rect: {width: number; height: number;}): number
{
return rect.width * rect.height;
}
此時如果呼叫CalculateArea({w:123,h:456}); 編譯器不會通過。
Object Types 還支援”?”表示可選引數
function CalculateArea(rect: {width:number; height:number; depth?:number;}): number
{
if(rect.depth)
{
return rect.width * rect.height * rect.depth;
}
return rect.width * rect.height;
}
CalculateArea({w:123,h:456}); //編譯器報錯
CalculateArea({width:123,height:456}); // 通過
CalculateArea({width:123,height:456,depth:789}); // 通過
可以這樣宣告一個Object
var example: {
name: string;
id: number;
collection: string[];
} = {
name: 'Example',
id: 5,
collection: ['a', 'b', 'c']
}
ActionScript3 :
var fun:Function;
var fun2:Function = someFunction;
TypeScript 可以指定Function需要的引數和返回值型別,叫做函式簽名,所以變成了這樣
var fun : (str: string) => void; // fun是輸入為string,沒有輸出的函式
var fun2 : (num: number) => number = someFnction; //someFnction函式必須輸入輸出都為number型別
eg.指定callback函式為string輸入,any輸出。
function vote(candidate: string, callback: (result: string) => any) {
// ...
}
vote("BigPig",
function(result: string) {
if (result === "BigPig") {
// ...
}
});
TypeScript 這樣的語法雖然使Function更清晰了,但也帶來麻煩,比如一個簡單的輸入輸出都是string的函式就要寫好長不易閱讀
var sayHello: (input: string) => string = function (s: string) {
return "Hello " + s;
}
//儲存函式的陣列也寫很長
var strArray: { (s: string): string; }[] = [sayHello, function aa(str: string) { return str; }]; //兩個輸入輸出都為string的函式
var strArray: { (s: string) => string; }[] //這樣寫會報錯,不知道為什麼要把 “=>”換成“ :” 不太清楚為什麼 -_-b
所以引入了 函式介面
函式介面
//定義輸入輸出都是字串的函式的介面
interface IStringFunction {
(input: string) : string;
}
上邊很長的都可以這麼寫了
var sayHello: IStringFunction = function (s: string) {
return "Hello " + s;
}
var strArray: IStringFunction[];
strArray.push(sayHello);
可選引數加”?”
//帶預設值
function func (a: number, b?: bool = false): number
{
if (b) { return a + b };
return a;
}
//不帶預設值,要自己判斷了
function func (a: number,b?: bool): number
{
if ( b !== null && b !== undefined )
{
if ( b) { return a + b };
}
return a;
}
rest引數 …paramName[:paramType]
function CountDwarvesTallerThan(minHeight: number, ...dwarves: Dwarf[]) : number
{
var count: number = 0;
for (var i = 0; i < dwarves.length; i++) {
if (dwarves[i].height > minHeight) {
count++;
}
}
return count;
}
Arrow Function
關於this作用域的問題,AS1時代經常用到的一個技巧:
var _this = this
var messenger = {
message: "Hello World",
start: function() {
var _this = this;
setTimeout(function() {
alert(_this.message);
}, 3000);
}
};
messenger.start();
TypeScript把這個技巧封裝到語言裡了,叫Arrow Function
語法格式為 ()=>{},例子:
TypeScript:
var messenger = {
message: "Hello World",
start: function() {
setTimeout(() => { alert(this.message); }, 3000);
}
};
messenger.start();
編譯後的JavaScript跟上邊的一樣
var messenger = {
message: "Hello World",
start: function () {
var _this = this;
setTimeout(function () {
alert(_this.message);
}, 3000);
}
};
messenger.start();
網上找到的一個例子,
//declare var 為環境宣告,用來告訴編譯器已知的變數型別,例如瀏覽器定義的一些變數型別
declare var menu: HTMLElement;
declare var sideBar: HTMLElement;
class UITester {
menuTouches: number;
sidebarTouches: number;
beginMenuTest(): void {
this.menuTouches = 0; // Right!!
menu.onmouseenter = function (e) {
this.menuTouches++; // Wrong!!
}
}
beginSidebarTest(): void {
this.sidebarTouches = 0; // Right!!
sideBar.onmousemove = e => {
this.sidebarTouches++; // Still right!!
}
}
}
語法中用了(e)=>{} ,將e傳給後邊的函式,並且省略了e的括號,會編譯成這樣:
var UITester = (function () {
function UITester() { }
UITester.prototype.beginMenuTest = function () {
this.menuTouches = 0;
menu.onmouseenter = function (e) {
this.menuTouches++;
};
};
UITester.prototype.beginSidebarTest = function () {
var _this = this;
this.sidebarTouches = 0;
sideBar.onmousemove = function (e) {
_this.sidebarTouches++;
};
};
return UITester;
})();
這裡有篇教程詳細解釋了這個語法:
http://www.codebelt.com/typescript/arrow-function-typescript-tutorial/
類相關的
TypeScript中的module相當於ActionScript3中的Package
TypeScript中建構函式的函式名用constructor ,而不用類名。
TypeScript:
module net.nshen {
export class Test1
{
private str: string = "abc"; // private property
public num: number = 123; //public property
public createTime: string; //createTime = undefined
constructor() // constructor
{
this.createTime = new Date().toUTCString();
}
static traceDate(): void
{
var currentDate: Date = new Date();
console.log(currentDate.toUTCString());
}
}
}
呼叫Static方法
net.nshen.Test1.traceDate();
module原理
module始終是要編譯成JS程式碼的,寫一個簡單的module看一下原理:
module M {
var s = "hello";
export function f() {
return s;
}
}
M.f();
M.s; // Error, s is not exported
編譯後的JS程式碼
var M;
(function(M) {
var s = "hello";
function f() {
return s;
}
M.f = f;
})(M||(M={}));
據說這是js界很流行的寫法,叫做JavaScript module pattern
函式過載
AS3和JS都是不支援函式過載的,TypeScript以一種雞肋的方式支援著。
先寫一些同名的函式宣告,最後在一個同名函式裡寫出實現(要自己判斷引數型別):
TypeScript:
function attr(name: string): string;
function attr(name: string, value: string): Accessor;
function attr(map: any): Accessor;
function attr(nameOrMap: any, value?: string): any {
if (nameOrMap && typeof nameOrMap === "object") {
// handle map case
}
else {
// handle string case
}
}
最終會編譯成一個JS方法:
JavaScript:
function attr(nameOrMap, value) {
if (nameOrMap && typeof nameOrMap === "object") {
} else {
}
}
2014/12/07 補充 : js判斷型別也是個很大的坑,詳見 http://tobyho.com/2011/01/28/checking-types-in-javascript/
TypeScript 允許多個類在同一個檔案裡,但如果類與類在不同的檔案,需要這種寫法,相當於AS3 的 import
/// <reference path="SimpleWebSocket.ts"/>
class ComplexWebSocket extends SimpleWebSocket {
...
}
override方法子類不需要寫關鍵字,直接同名方法即可 ,可呼叫super.xxx()
class Base {
public test():number
{
return 1;
}
public test2():number
{
return 2;
}
}
class Derived extends Base {
public test():number
{
return 3;
}
public test2():number
{
return super.test();
}
}
var d:Derived = new Derived();
console.log(d.test()); // 3
console.log(d.test2());// 1
Enum
TypeScript支援enum關鍵字
enum Color { Red, Green, Blue }
console.log(Color.Red); // 0
var c:number = Color.Green;
console.log(Color[c]) //Green
生成對應的js
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
console.log(Color.Red);
var c = Color.Green;
console.log(Color[c]);//Green
基礎型別只有這麼幾種,與AS3對比
TypeScript ActionScript3
number Number
string String
boolean(0.8以前為bool) Boolean
any *
undefined undefined
null null
任意型別:
ActionScript3 :
var anyType : * = ...;
TypeScript:
var anyType : any = ...;
變數修飾符:
TS類似AS3 但不用寫”var” , 沒有protected (未來也許會新增),預設為public。
ActionScript3 :
private var str: String = "abc";
public var num: Number = 123;
var num2 :Number = 456;
static var bo: Boolean = true;
public var createTime: String;
TypeScript:
private str: string = "abc"; // private property
public num: number = 123; // public property
num2 :number = 456; // 不寫預設也為public
static bo: boolean = true; // static
public createTime: string; //createTime 型別為string,值為 undefined
變數型別轉換:
ActionScript3 :
var str:String = "abc";
var strNum:Number = Number(str);
var strNum:Number = str as Number;
TypeScript :
var str : string = "abc";
var strNum: number = <number> str; //編譯報錯 Cannot convert 'string' to 'number'
發現使用any型別會編譯通過:
var str2 :any = "abc"; //any型別
var strNum2 :number = <number> str2; //通過
strNum2 += 5; // abc5
用 instanceof 判斷型別
// instanceof
function CalculateArea(shape : Shape) : number {
if (shape instanceof Square) {
return (<Square>shape).x * (<Square>shape).y;
}
if (shape instanceof Ellipse) {
return (<Ellipse>shape).r1 * (<Ellipse>shape).r2 * Math.PI;
}
if (shape instanceof Triangle) {
return 0.5 * (<Triangle>shape).x * (<Triangle>shape).y;
}
throw new TypeError("Unsupported type!");
}
陣列
Typescript陣列的寫法比AS3漂亮很多
ActionScript3 :
var arr:Array = [1,2,3,"a","b","c"]; // 任意型別陣列
var strArray:Vector.<String> = Vector.<String>(["a", "b", "c"]); //固定型別陣列
TypeScript :
var arr: any[] = new Array(); // 任意型別陣列
var strArr: string[] = ["a", "b", "c" ]; //固定型別陣列
二維陣列
var array2d: string[][] = [
["a", "b", "c"],
["x", "y", "z"]
];
// or
var array2d: string[][] = new Array();
array2d.push(["a", "b", "c"]);
array2d.push(["x", "y", "z"]);
Object Types
當AS3呼叫這樣一個函式時,會有下面一個問題。
ActionScript3 :
function CalculateArea ( rect : Object ):Number
{
return rect.width * rect.height;
}
此時編譯器並不知道rect這個Object裡到底有沒有width和height,只能等到runtime時才會知道。
TypeScript 引入Object Types解決這一問題,可以指定Object引數的具體內容,相當於讓Object引數實現了interface
function CalculateArea(rect: {width: number; height: number;}): number
{
return rect.width * rect.height;
}
此時如果呼叫CalculateArea({w:123,h:456}); 編譯器不會通過。
Object Types 還支援”?”表示可選引數
function CalculateArea(rect: {width:number; height:number; depth?:number;}): number
{
if(rect.depth)
{
return rect.width * rect.height * rect.depth;
}
return rect.width * rect.height;
}
CalculateArea({w:123,h:456}); //編譯器報錯
CalculateArea({width:123,height:456}); // 通過
CalculateArea({width:123,height:456,depth:789}); // 通過
可以這樣宣告一個Object
var example: {
name: string;
id: number;
collection: string[];
} = {
name: 'Example',
id: 5,
collection: ['a', 'b', 'c']
}
ActionScript3 :
var fun:Function;
var fun2:Function = someFunction;
TypeScript 可以指定Function需要的引數和返回值型別,叫做函式簽名,所以變成了這樣
var fun : (str: string) => void; // fun是輸入為string,沒有輸出的函式
var fun2 : (num: number) => number = someFnction; //someFnction函式必須輸入輸出都為number型別
eg.指定callback函式為string輸入,any輸出。
function vote(candidate: string, callback: (result: string) => any) {
// ...
}
vote("BigPig",
function(result: string) {
if (result === "BigPig") {
// ...
}
});
TypeScript 這樣的語法雖然使Function更清晰了,但也帶來麻煩,比如一個簡單的輸入輸出都是string的函式就要寫好長不易閱讀
var sayHello: (input: string) => string = function (s: string) {
return "Hello " + s;
}
//儲存函式的陣列也寫很長
var strArray: { (s: string): string; }[] = [sayHello, function aa(str: string) { return str; }]; //兩個輸入輸出都為string的函式
var strArray: { (s: string) => string; }[] //這樣寫會報錯,不知道為什麼要把 “=>”換成“ :” 不太清楚為什麼 -_-b
所以引入了 函式介面
函式介面
//定義輸入輸出都是字串的函式的介面
interface IStringFunction {
(input: string) : string;
}
上邊很長的都可以這麼寫了
var sayHello: IStringFunction = function (s: string) {
return "Hello " + s;
}
var strArray: IStringFunction[];
strArray.push(sayHello);
可選引數加”?”
//帶預設值
function func (a: number, b?: bool = false): number
{
if (b) { return a + b };
return a;
}
//不帶預設值,要自己判斷了
function func (a: number,b?: bool): number
{
if ( b !== null && b !== undefined )
{
if ( b) { return a + b };
}
return a;
}
rest引數 …paramName[:paramType]
function CountDwarvesTallerThan(minHeight: number, ...dwarves: Dwarf[]) : number
{
var count: number = 0;
for (var i = 0; i < dwarves.length; i++) {
if (dwarves[i].height > minHeight) {
count++;
}
}
return count;
}
Arrow Function
關於this作用域的問題,AS1時代經常用到的一個技巧:
var _this = this
var messenger = {
message: "Hello World",
start: function() {
var _this = this;
setTimeout(function() {
alert(_this.message);
}, 3000);
}
};
messenger.start();
TypeScript把這個技巧封裝到語言裡了,叫Arrow Function
語法格式為 ()=>{},例子:
TypeScript:
var messenger = {
message: "Hello World",
start: function() {
setTimeout(() => { alert(this.message); }, 3000);
}
};
messenger.start();
編譯後的JavaScript跟上邊的一樣
var messenger = {
message: "Hello World",
start: function () {
var _this = this;
setTimeout(function () {
alert(_this.message);
}, 3000);
}
};
messenger.start();
網上找到的一個例子,
//declare var 為環境宣告,用來告訴編譯器已知的變數型別,例如瀏覽器定義的一些變數型別
declare var menu: HTMLElement;
declare var sideBar: HTMLElement;
class UITester {
menuTouches: number;
sidebarTouches: number;
beginMenuTest(): void {
this.menuTouches = 0; // Right!!
menu.onmouseenter = function (e) {
this.menuTouches++; // Wrong!!
}
}
beginSidebarTest(): void {
this.sidebarTouches = 0; // Right!!
sideBar.onmousemove = e => {
this.sidebarTouches++; // Still right!!
}
}
}
語法中用了(e)=>{} ,將e傳給後邊的函式,並且省略了e的括號,會編譯成這樣:
var UITester = (function () {
function UITester() { }
UITester.prototype.beginMenuTest = function () {
this.menuTouches = 0;
menu.onmouseenter = function (e) {
this.menuTouches++;
};
};
UITester.prototype.beginSidebarTest = function () {
var _this = this;
this.sidebarTouches = 0;
sideBar.onmousemove = function (e) {
_this.sidebarTouches++;
};
};
return UITester;
})();
這裡有篇教程詳細解釋了這個語法:
http://www.codebelt.com/typescript/arrow-function-typescript-tutorial/
類相關的
TypeScript中的module相當於ActionScript3中的Package
TypeScript中建構函式的函式名用constructor ,而不用類名。
TypeScript:
module net.nshen {
export class Test1
{
private str: string = "abc"; // private property
public num: number = 123; //public property
public createTime: string; //createTime = undefined
constructor() // constructor
{
this.createTime = new Date().toUTCString();
}
static traceDate(): void
{
var currentDate: Date = new Date();
console.log(currentDate.toUTCString());
}
}
}
呼叫Static方法
net.nshen.Test1.traceDate();
module原理
module始終是要編譯成JS程式碼的,寫一個簡單的module看一下原理:
module M {
var s = "hello";
export function f() {
return s;
}
}
M.f();
M.s; // Error, s is not exported
編譯後的JS程式碼
var M;
(function(M) {
var s = "hello";
function f() {
return s;
}
M.f = f;
})(M||(M={}));
據說這是js界很流行的寫法,叫做JavaScript module pattern
函式過載
AS3和JS都是不支援函式過載的,TypeScript以一種雞肋的方式支援著。
先寫一些同名的函式宣告,最後在一個同名函式裡寫出實現(要自己判斷引數型別):
TypeScript:
function attr(name: string): string;
function attr(name: string, value: string): Accessor;
function attr(map: any): Accessor;
function attr(nameOrMap: any, value?: string): any {
if (nameOrMap && typeof nameOrMap === "object") {
// handle map case
}
else {
// handle string case
}
}
最終會編譯成一個JS方法:
JavaScript:
function attr(nameOrMap, value) {
if (nameOrMap && typeof nameOrMap === "object") {
} else {
}
}
2014/12/07 補充 : js判斷型別也是個很大的坑,詳見 http://tobyho.com/2011/01/28/checking-types-in-javascript/
TypeScript 允許多個類在同一個檔案裡,但如果類與類在不同的檔案,需要這種寫法,相當於AS3 的 import
/// <reference path="SimpleWebSocket.ts"/>
class ComplexWebSocket extends SimpleWebSocket {
...
}
override方法子類不需要寫關鍵字,直接同名方法即可 ,可呼叫super.xxx()
class Base {
public test():number
{
return 1;
}
public test2():number
{
return 2;
}
}
class Derived extends Base {
public test():number
{
return 3;
}
public test2():number
{
return super.test();
}
}
var d:Derived = new Derived();
console.log(d.test()); // 3
console.log(d.test2());// 1
Enum
TypeScript支援enum關鍵字
enum Color { Red, Green, Blue }
console.log(Color.Red); // 0
var c:number = Color.Green;
console.log(Color[c]) //Green
生成對應的js
var Color;
(function (Color) {
Color[Color["Red"] = 0] = "Red";
Color[Color["Green"] = 1] = "Green";
Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
console.log(Color.Red);
var c = Color.Green;
console.log(Color[c]);//Green