使用ts完成一個todomvc的demoreact
interface LabelledValue { label: string; } function printLabel(labelledObj: LabelledValue) { console.log(labelledObj.label); } let myObj = {size: 10, label: "Size 10 Object"}; printLabel(myObj);
接口能夠用來校驗參數的類型,參數是否存在等等。webpack
interface SquareConfig { color?: string; width?: number; } function createSquare(config: SquareConfig): { color: string; area: number } { let newSquare = {color: "white", area: 100}; if (config.clor) { // Error: Property 'clor' does not exist on type 'SquareConfig' newSquare.color = config.clor; } if (config.width) { newSquare.area = config.width * config.width; } return newSquare; } let mySquare = createSquare({color: "black"});
interface Point { readonly x: number; readonly y: number; } let p1: Point = { x: 10, y: 20 }; p1.x = 5; // error!
對象字面量形式會被特殊對待並且會通過額外屬性檢查
interface SquareConfig { color?: string; width?: number; } function createSquare(config: SquareConfig): { color: string; area: number } { let newSquare = { color: "white", area: 100 }; if (config.clor) { // Error: Property 'clor' does not exist on type 'SquareConfig' newSquare.color = config.clor; } if (config.width) { newSquare.area = config.width * config.width; } return newSquare; } let mySquare = createSquare({ color: "black" }); createSquare({ colour: "red", width: 100 }); // Error: Property 'colour does no exist on type 'SquareConfig'
若是想解決這個問題有三種解決辦法git
// 1. 將對象字面量複製給變量,傳入變量不會被進行額外屬性檢查 let skipLiteral = { colour: "red", width: 100 }; createSquare(skipLiteral); // 2.採用類型斷言,使用as操做符,告訴編譯器我傳入的參數對象就是你要的類型 createSquare({ colour: "red", width: 100 } as SquareConfig); // 3.第三種方式,添加萬能校驗符,這個符號會包容color、width以外全部其餘屬性,慎用 interface SquareConfig { color?: string; width?: number; [propName: string]: any; }
interface SearchFunc { (source: string, subString: string): boolean; }
interface StringArray { [index: number]: string; } let myArray: StringArray; myArray = ["Bob", "Fred"]; let myStr: string = myArray[0];
ts支持兩種索引簽名,字符串和數值,同時使用的時候,數值索引返回的類型必須是字符串索引返回類型的子類,由於js解析的時候會將數值索引轉換爲字符串索引,因此數值索引返回的類型必須與字符串返回的類型保持一致(或子類)。github
class Animal { name: string; } class Dog extends Animal { breed: string; } // 錯誤:使用數值型的字符串索引,有時會獲得徹底不一樣的Animal! interface NotOkay { [x: number]: Animal; [x: string]: Dog; }
與C#或Java裏接口的基本做用同樣,TypeScript也可以用它來明確的強制一個類去符合某種契約。web
interface ClockInterface { currentTime: Date; } class Clock implements ClockInterface { currentTime: Date; constructor(h: number, m: number) { } }
interface Shape { color: string; } interface Square extends Shape { sideLength: number; }
class Animal { move(distanceInMeters: number = 0) { console.log(`Animal moved ${distanceInMeters}m.`); } } class Dog extends Animal { bark() { console.log('Woof! Woof!'); } } const dog = new Dog(); dog.bark(); dog.move(10); dog.bark();
let passcode = "secret passcode"; class Employee { private _fullName: string; get fullName(): string { return this._fullName; } set fullName(newName: string) { if (passcode && passcode == "secret passcode") { this._fullName = newName; } else { console.log("Error: Unauthorized update of employee!"); } } } let employee = new Employee(); employee.fullName = "Bob Smith"; if (employee.fullName) { alert(employee.fullName); }
class Grid { static origin = {x: 0, y: 0}; calculateDistanceFromOrigin(point: {x: number; y: number;}) { let xDist = (point.x - Grid.origin.x); let yDist = (point.y - Grid.origin.y); return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale; } constructor (public scale: number) { } } let grid1 = new Grid(1.0); // 1x scale let grid2 = new Grid(5.0); // 5x scale console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10})); console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
class Point { x: number; y: number; } interface Point3d extends Point { z: number; } let point3d: Point3d = {x: 1, y: 2, z: 3};
let myAdd: (x: number, y: number) => number = function(x: number, y: number): number { return x + y; };
方法是爲同一個函數提供多個函數類型定義來進行函數重載。 編譯器會根據這個列表去處理函數的調用。typescript
let suits = ["hearts", "spades", "clubs", "diamonds"]; function pickCard(x: {suit: string; card: number; }[]): number; function pickCard(x: number): {suit: string; card: number; }; function pickCard(x): any { // Check to see if we're working with an object/array // if so, they gave us the deck and we'll pick the card if (typeof x == "object") { let pickedCard = Math.floor(Math.random() * x.length); return pickedCard; } // Otherwise just let them pick the card else if (typeof x == "number") { let pickedSuit = Math.floor(x / 13); return { suit: suits[pickedSuit], card: x % 13 }; } } let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }]; let pickedCard1 = myDeck[pickCard(myDeck)]; alert("card: " + pickedCard1.card + " of " + pickedCard1.suit); let pickedCard2 = pickCard(15); alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);
function identity<T>(arg: T): T { return arg; }
使用尖括號傳入泛型變量,它會根據參會類型智能賦值。好比arg是number,那麼T就會被賦值爲number。mvc
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; };
在這裏,泛型做爲一種變量,可供用戶調用的時候動態約束類屬性。dom
function getProperty(obj: T, key: K) { return obj[key]; } let x = { a: 1, b: 2, c: 3, d: 4 }; getProperty(x, "a"); // okay getProperty(x, "m"); // error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.