建了個羣有興趣的朋友能夠加一下 QQ 羣:Angular 修仙之路(1)羣 - 153742079 (已滿),請加 Angular 修仙之路(2)羣 - 648681235。html
TypeScript 是一種由微軟開發的自由和開源的編程語言。它是 JavaScript 的一個超集,並且本質上向這個語言添加了可選的靜態類型和基於類的面向對象編程。
TypeScript 擴展了 JavaScript 的句法,因此任何現有的 JavaScript 程序能夠不加改變的在 TypeScript 下工做。TypeScript 是爲大型應用之開發而設計,而編譯時它產生 JavaScript 以確保兼容性。node
$ npm install -g typescript
$ tsc app.ts # app.ts => app.js
let isDone: boolean = false; // tsc => var isDone = false;
let count: number = 10; // tsc => var count = 10
let name: string = 'Semliker'; // tsc => var name = 'Semlinker'
let list: number[] = [1,2,3]; // tsc => var list = [1,2,3]; let list: Array<number> = [1,2,3]; // tsc => var list = [1,2,3];
enum Direction { NORTH, SOUTH, EAST, WEST }; let dir: Direction = Direction.NORTH;
let notSure: any = 4; notSure = "maybe a string instead"; notSure = false; => tsc => var notSure = 4; notSure = "maybe a string instead"; notSure = false;
某種程度上來講,void 類型像是與 any 類型相反,它表示沒有任何類型。當一個函數沒有返回值時,你一般會見到其返回值類型是 void:react
// 聲明函數返回值爲void function warnUser(): void { console.log("This is my warning message"); } => tsc => function warnUser() { console.log("This is my warning message"); }
須要注意的是,聲明一個 void 類型的變量沒有什麼做用,由於它的值只能爲 undefined
或 null
:typescript
let unusable: void = undefined;
元組類型容許表示一個已知元素數量和類型的數組,各元素的類型沒必要相同。好比,你能夠定義一對值分別爲 string
和 number
類型的元組。shell
let x: [string, number]; x = ['semlinker', 10]; // 正常賦值 x = [10, 'semlinker']; // 類型不匹配
當訪問一個已知索引的元素,會獲得正確的類型:express
console.log(x[0].substr(1)); // OK // Error, 'number' does not have 'substr' method console.log(x[1].substr(1));
當訪問一個越界的元素,會使用聯合類型替代:npm
x[3] = 'world'; // OK, 字符串能夠賦值給(string | number) 類型 console.log(x[5].toString()); // OK, 'string' 和 'number' 都有 toString 方法 x[6] = true; // Error, 布爾不是(string | number) 類型
有時候你會遇到這樣的狀況,你會比 TypeScript 更瞭解某個值的詳細信息。一般這會發生在你清楚地知道一個實體具備比它現有類型更確切的類型。編程
經過類型斷言這種方式能夠告訴編譯器,"相信我,我知道本身在幹什麼"。類型斷言比如其餘語言裏的類型轉換,可是不進行特殊的數據檢查和解構。它沒有運行時的影響,只是在編譯階段起做用。json
類型斷言有兩種形式:數組
"尖括號"語法
let someValue: any = "this is a string"; let strLength: number = (<string>someValue).length;
as 語法
let someValue: any = "this is a string"; let strLength: number = (someValue as string).length;
let greet = (message: string | string[]) => { if(message instanceof Array) { let messages = ""; message.forEach((msg) => { messages += ` ${msg}`; }); console.log("Received messages ", messages); } else { console.log("Received message = ", message); } }; greet('semlinker'); greet(['Hello', 'Angular']);
type Message = string | string[]; let greet = (message: Message) => { // ... };
TypeScript | JavaScript |
---|---|
Types | No types |
Arrow function | Arrow function (ES2015) |
Function types | No Function types |
Required and Optional parameters | All parameters are optional |
Default parameters | Default parameters |
Rest parameters | Rest parameters |
Overloaded function | No overloaded functions |
常見語法
myBooks.forEach(() => console.log('Done reading')); myBooks.forEach(title => console.log(title)); myBooks.forEach((title, idx, arr) => console.log(idx + '-' + title); ); myBooks.forEach((title, idx, arr) => { console.log(idx + '-' + title); });
使用示例
// 未使用箭頭函數 function Book() { let self = this; self.publishDate = 2016; setInterval(function() { console.log(self.publishDate); }, 1000); } // 使用箭頭函數 function Book() { this.publishDate = 2016; setInterval(() => { console.log(this.publishDate); }, 1000); }
function createUserId(name: string, id: number): string { return name + id; }
let IdGenerator: (chars: string, nums: number) => string; function createUserId(name: string, id: number): string { return name + id; } IdGenerator = createUserId;
// 可選參數 function createUserId(name: string, age?: number, id: number): string { return name + id; } // 默認參數 function createUserId(name: string = 'Semlinker', age?: number, id: number): string { return name + id; }
function push(array, ...items) { items.forEach(function(item) { array.push(item); }); } let a = []; push(a, 1, 2, 3);
let x: number, let y: number ,let z: number; let five_array = [0,1,2,3,4]; [x,y,z] = five_array;
let two_array = [0,1]; let five_array = [...two_array,2,3,4];
let colors: string[] = ["red", "green", "blue"]; for(let i in colors) { console.log(i); }
let person = { name: 'Semlinker', gender: 'male' }; let {name, gender} = person;
let person = { name: 'Semlinker', gender: 'male', address: 'Xiamen' }; // 組裝對象 let personWithAge = {...person, age: 31}; // 獲取除了某些項外的其它項 let {name, ...rest} = person;
在面嚮對象語言中,接口(Interfaces)是一個很重要的概念,它是對行爲的抽象,而具體如何行動須要由類(classes)去實現(implements)。
TypeScript 中的接口是一個很是靈活的概念,除了可用於對類的一部分行爲進行抽象之外,也經常使用於對「對象的形狀(Shape)」進行描述。
interface Person { name: string; age: number; } let semlinker: Person = { name: 'Semlinker', age: 31 };
interface Person { readonly name: string; age?: number; }
在面嚮對象語言中,類是一種面向對象計算機編程語言的構造,是建立對象的藍圖,描述了所建立的對象共同的屬性和方法。
在 TypeScript 中,咱們能夠經過 Class
關鍵字來定義一個類:
class Greeter { static cname: string = 'Greeter'; // 靜態屬性 greeting: string; // 成員屬行 constructor(message: string) { // 構造函數 - 執行初始化操做 this.greeting = message; } static getClassName() { // 靜態方法 return 'Class name is Greeter'; } greet() { // 成員方法 return "Hello, " + this.greeting; } } let greeter = new Greeter("world");
在 TypeScript 中,咱們能夠經過 getter
和 setter
方法來實現數據的封裝和有效性校驗,防止出現異常數據。
let passcode = "hello angular 5"; class Employee { private _fullName: string; get fullName(): string { return this._fullName; } set fullName(newName: string) { if (passcode && passcode == "hello angular 5") { this._fullName = newName; } else { console.log("Error: Unauthorized update of employee!"); } } } let employee = new Employee(); employee.fullName = "Bob Smith"; if (employee.fullName) { console.log(employee.fullName); }
繼承 (Inheritance) 是一種聯結類與類的層次模型。指的是一個類 (稱爲子類、子接口) 繼承另外的一個類 (稱爲父類、父接口) 的功能,並能夠增長它本身的新功能的能力,繼承是類與類或者接口與接口之間最多見的關係;繼承是一種 is-a 關係。
在 TypeScripe 中,咱們能夠經過 extends
關鍵字來實現繼承:
class Animal { name: string; constructor(theName: string) { this.name = theName; } move(distanceInMeters: number = 0) { console.log(`${this.name} moved ${distanceInMeters}m.`); } } class Snake extends Animal { constructor(name: string) { super(name); } move(distanceInMeters = 5) { console.log("Slithering..."); super.move(distanceInMeters); } } let sam = new Snake("Sammy the Python"); sam.move();
泛型(Generics)是容許同一個函數接受不一樣類型參數的一種模板。相比於使用 any 類型,使用泛型來建立可複用的組件要更好,由於泛型會保留參數類型。
interface GenericIdentityFn<T> { (arg: T): T; }
class GenericNumber<T> { zeroValue: T; add: (x: T, y: T) => T; } let myGenericNumber = new GenericNumber<number>(); myGenericNumber.zeroValue = 0; myGenericNumber.add = function(x, y) { return x + y; };
interface Hero { // Hero 接口 id: number; name: string; } getHeroes(): Observable<Hero[]> { return Observable.of([ { id: 1, name: 'Windstorm' }, { id: 13, name: 'Bombasto' }, { id: 15, name: 'Magneta' }, { id: 20, name: 'Tornado' } ]); }
上面 getHeroes(): Observable<Hero[]>
表示調用 getHeroes()
方法後返回的是一個 Observable 對象,<Hero[]>
用於表示該 Observable 對象的觀察者,將會收到的數據類型。示例中表示將會返回 <Hero[]>
英雄列表。
用於標識 TypeScript 項目的根路徑
用於配置 TypeScript 編譯器
用於指定編譯的文件
files - 設置要編譯的文件的名稱
include - 設置須要進行編譯的文件,支持路徑模式匹配
exclude - 設置無需進行編譯的文件,支持路徑模式匹配
compilerOptions - 設置與編譯流程相關的選項
字段 | 說明 |
---|---|
target | Desired ECMAScript version (es3,es5,es2015,es2016,es2017, or esNext) |
rootDir | Root directory of input files |
listFiles | Print file names processed by the compiler |
outDir | Directory to contain compiled results |
outFile | File to contain concatenated results |
watch | Watch input files |
removeComments | Remove comments from generated output |
noLib | Don't include the main library, lib.d.ts, in the compilation process |
alwaysStrict | Specifies whether strict mode should be enabled |
noEmitOnError | Don't generate output if any errors were encounted |
noImplicitThis | Raise an error on this expressions with implied any type |
noUnuseLocals | Report errors on unused parameters |
noImplicitAny | Print a warning for every variable that isn't explicitly declared |
suppressImplicit Any IndexErrors | Suppress Implicit AnyIndexError |
skipLibCheck | Suppress type checking of declarations files |
experimental Decorators | Enable support for ES7 decorators |
declaration | Generate declaration file(*.d.ts) for the TypeScript code |
declarationDir | Place declaration files in the given directory |
module | The formate of the generated module (commonjs, amd, system, umd, or es2015) |
noEmitHelpers | Do not insert custom helper functions in generated output |
emitDecoratorMetadata | Insert metadata for TypeScript decorations |
isolatedModule | Always insert imports for unresolved files |
jsx | Generate JSC code (preserve or react) |
moduleResolution | Strategy for resolving module (node or classic) |
{ "files": ["src/app/app.ts"], "compilerOptions": { "target": "es5", "removeComments": true, "alwaysStrict": true, "noEmitOnError": true, "noUnusedLocals": true, "noUnusedParameters": true } }
alwaysStrict - ES 5 代碼將在嚴格模式下執行
noEmitOnError - 表示當發生錯誤的時候,編譯器不要生成 JavaScript 代碼
noUnusedLocals 和 noUnusedParameters - 表示編譯器將檢測沒有使用的變量或參數