函數(shù)聲明
為函數(shù)定義類型
function hi(name:string): void {
console.log(`hi ${name}`)
}
可選參數(shù)晌柬、默認參數(shù)质欲、類型推斷、剩余參數(shù)
function hi(name: string, age?:number):void {} // 可選參數(shù) age
function hi(name: string, age = 18): void{} // age 默認參數(shù)18 推斷age的類型為number
function hi(name:string, age:number = 19): string | number{} // 可以給默認參數(shù)類型祠丝。 返回string或者number
function buildName(firstName: string, ...restOfName: string[]) { // 剩余參數(shù)
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
泛型
function identity(arg: any): any { // 我們可以傳入number而返回string
return arg;
}
我們需要一種方法使返回值的類型與傳入?yún)?shù)的類型是相同的
這里疾呻,我們使用了 類型變量除嘹,它是一種特殊的變量,只用于表示類型而不是值岸蜗。
function identity<T>(arg: T): T { // T幫助我們捕獲用戶傳入的類型
return arg;
}
我們定義了泛型函數(shù)后尉咕,可以用兩種方法使用。 第一種是璃岳,傳入所有的參數(shù)年缎,包含類型參數(shù):
let output = identity<string>("myString"); // type of output will be 'string'
第二種方法更普遍。利用了類型推論 -- 即編譯器會根據(jù)傳入的參數(shù)自動地幫助我們確定T的類型:
let output = identity("myString"); // type of output will be 'string'
會出現(xiàn)如下的報錯铃慷, 我們使用了arg的.length屬性单芜,但是沒有地方指明arg具有這個屬性。 (泛型約束會提及)
function loggingIdentity<T>(arg: T): T {
console.log(arg.length); // Error: T doesn't have .length
return arg;
}
我們可以這樣(泛型約束會提及)
function loggingIdentity<T>(arg: T[]): T[] {
console.log(arg.length); // Array has a .length, so no more error
return arg;
}
泛型接口
interface GenericIdentityFn {
<T>(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn = identity;
interface GenericIdentityFn<T> {
(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
泛型類
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; };
泛型約束
我們想訪問arg的length屬性犁柜,但是編譯器并不能證明每種類型都有l(wèi)ength屬性洲鸠,所以就報錯了。
創(chuàng)建一個包含 .length屬性的接口馋缅,使用這個接口和extends關(guān)鍵字來實現(xiàn)約束:
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // Now we know it has a .length property, so no more error
return arg;
}
現(xiàn)在這個泛型函數(shù)被定義了約束扒腕,因此它不再是適用于任意類型:
loggingIdentity(3); // Error, number doesn't have a .length property
我們需要傳入符合約束類型的值,必須包含必須的屬性:
loggingIdentity({length: 10, value: 3});
重載
function add(a: number, b:number):number;
function add(a: string, b:string):string;
function add(a: any, b: any): any {
return a + b
}
類型兼容
interface Named {
name: string;
}
let x: Named;
let y = { name: 'Alice', location: 'Seattle' };
x = y;
Unsound 不完備的股囊。有瑕疵的袜匿。
enum EventType { Mouse, Keyboard }
interface Event { timestamp: number; }
interface MouseEvent extends Event { x: number; y: number }
interface KeyEvent extends Event { keyCode: number }
function listenEvent(eventType: EventType, handler: (n: Event) => void) {
/* ... */
}
// Unsound, but useful and common
listenEvent(EventType.Mouse, (e: MouseEvent) => console.log(e.x + ',' + e.y)); // 有瑕疵的,但是不會報錯稚疹。mouseEvent是Event的子類型
// Undesirable alternatives in presence of soundness
listenEvent(EventType.Mouse, (e: Event) => console.log((<MouseEvent>e).x + ',' + (<MouseEvent>e).y)); // 使用了類型斷言
listenEvent(EventType.Mouse, <(e: Event) => void>((e: MouseEvent) => console.log(e.x + ',' + e.y))); // 這個看不懂
listenEvent(EventType.Mouse, (e: number) => console.log(e)); // 完全不一致所以會報錯
```