1.函數(shù)的類型
// 1.函數(shù)作為參數(shù)時, 在參數(shù)中如何編寫類型
function foo() {}
type FooFnType = () => void;
function bar(fn: FooFnType) {
fn();
}
bar(foo);
// 2.定義常量時, 編寫函數(shù)的類型
type AddFnType = (num1: number, num2: number) => number;
const add: AddFnType = (a1: number, a2: number) => {
return a1 + a2;
};
2 函數(shù)類型的案例
function calc(n1: number, n2: number, fn: (num1: number, num2: number) => number) {
return fn(n1, n2)
}
const result1 = calc(20, 30, function(a1, a2) {
return a1 + a2
})
console.log(result1)
const result2 = calc(20, 30, function(a1, a2) {
return a1 * a2
})
console.log(result2)
3.函數(shù)的可選類型
// 可選類型是必須寫在必選類型的后面的
// y -> undefined | number
function foo(x: number, y?: number) {
}
foo(20, 30)
foo(20)
4.默認(rèn)參數(shù)
// 必傳參數(shù) - 有默認(rèn)值的參數(shù) - 可選參數(shù)
function foo(y: number, x: number = 20) {
console.log(x, y)
}
foo(30)
function foo(x:number = 20, y:number) {
console.log(x, y)
}
foo(undefined, 30)
5.剩余參數(shù)
從ES6開始翰守,JavaScript也支持剩余參數(shù)谅摄,剩余參數(shù)語法允許我們將一個不定數(shù)量的參數(shù)放到一個數(shù)組中冰寻。
// function sum(num1: number, num2: number) {
// return num1 + num2
// }
function sum(initalNum: number, ...nums: number[]) {
let total = initalNum
for (const num of nums) {
total += num
}
return total
}
console.log(sum(20, 30))
console.log(sum(20, 30, 40))
console.log(sum(20, 30, 40, 50))
6.可推導(dǎo)的this類型
// this是可以被推導(dǎo)出來 info對象(TypeScript推導(dǎo)出來)
//pTypeScript認(rèn)為函數(shù) eating 有一個對應(yīng)的this的外部對象 info揣钦,所以在使用時计贰,就會把this當(dāng)做該對象孔厉。
const info = {
name: "why",
eating() {
console.log(this.name + " eating");
},
};
info.eating(); //why eating
export {};
7.不確定的this類型
function eating() {
console.log(this.name + " eating");
}
const info = {
name: "why",
eating: eating,
};
info.eating();
/*
直接報錯
test.ts:2:15 - error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
獨(dú)立函數(shù)推導(dǎo)不出來this
*/
8.指定this的類型
這個時候聂抢,通常TypeScript會要求我們明確的指定this的類型:
type ThisType = { name: string };
function eating(this: ThisType) {
console.log(this.name + " eating");
}
const info = {
name: "why",
eating: eating,
};
// 隱式綁定
info.eating();//why eating
export {};
type ThisType = { name: string };
function eating(this: ThisType) {
console.log(this.name + " eating");
}
const info = {
name: "why",
eating: eating,
};
// 隱式綁定
info.eating(); //why eating
//eating();
/* The 'this' context of type 'void' is not assignable to method's 'this' of type 'ThisType'.
直接eating的話是會報錯的凌外,因?yàn)闆]有指定this的類型,this似乎一個對象類型涛浙,里面有個string類型的name */
//可以通過以下方式
eating.call({ name: "kobe" });
eating.apply({ name: "james" });
/*
kobe eating
james eating */
export {};
9.函數(shù)的重載(聯(lián)合類型)
function sum(n1: string | number, n2: string | number): string | number {
return n1 + n2;
}
/*
這么寫n1 + n2會報錯
因?yàn)閚1的類型是string | number
n2的類型是string | number
他們兩個類型之間是不能進(jìn)行相加的
*/
如何解決
/**
* 通過聯(lián)合類型有兩個缺點(diǎn):
* 1.進(jìn)行很多的邏輯判斷(類型縮小)
* 2.返回值的類型依然是不能確定(any類型)
*/
function add(a1: number | string, a2: number | string) {
if (typeof a1 === "number" && typeof a2 === "number") {
return a1 + a2
} else if (typeof a1 === "string" && typeof a2 === "string") {
return a1 + a2
}
// return a1 + a2;
}
add(10, 20)
10. 函數(shù)的重載(函數(shù)重載)
比如我們對sum函數(shù)進(jìn)行重構(gòu):
在我們調(diào)用sum的時候康辑,它會根據(jù)我們傳入的參數(shù)類型來決定執(zhí)行函數(shù)體時,到底執(zhí)行哪一個函數(shù)的重載簽名轿亮;
// 函數(shù)的重載: 函數(shù)的名稱相同, 但是參數(shù)不同的幾個函數(shù), 就是函數(shù)的重載
function add(num1: number, num2: number): number; // 沒函數(shù)體
function add(num1: string, num2: string): string;
function add(num1: any, num2: any): any {
if (typeof num1 === "string" && typeof num2 === "string") {
return num1.length + num2.length;
}
return num1 + num2;
}
const result = add(20, 30); //從上往下一次匹配疮薇,于是就匹配到第一個add,但是第一個add沒有函數(shù)體我注,于是就執(zhí)行第三個add的函數(shù)體按咒,,也就是實(shí)現(xiàn)函數(shù)
const result2 = add("abc", "cba");
console.log(result);
console.log(result2);
// 在函數(shù)的重載中, 實(shí)現(xiàn)函數(shù)是不能直接被調(diào)用的但骨,只有在匹配之后励七,實(shí)現(xiàn)函數(shù)才能被調(diào)用
// add({name: "why"}, {age: 18})
export {};
11.聯(lián)合類型和函數(shù)重載對比
就是如果能通過聯(lián)合類型方便簡單的實(shí)現(xiàn)的情況下,盡量使用我們的聯(lián)合類型奔缠,因?yàn)楦唵温犹В驗(yàn)闊o論string和數(shù)組,都有l(wèi)ength屬性校哎,所以聯(lián)合類型可以實(shí)現(xiàn)两波,實(shí)現(xiàn)起來很簡潔瞳步,函數(shù)的重載反而有些麻煩。
如果通過聯(lián)合類型發(fā)現(xiàn)實(shí)現(xiàn)起來非常麻煩的情況下腰奋,我才會使用函數(shù)重載单起。
// 實(shí)現(xiàn)方式一: 聯(lián)合類型
function getLength(args: string | any[]) {
return args.length
}
console.log(getLength("abc"))
console.log(getLength([123, 321, 123]))
// 實(shí)現(xiàn)方式二: 函數(shù)的重載
// function getLength(args: string): number;
// function getLength(args: any[]): number;
// function getLength(args: any): number {
// return args.length
// }
// console.log(getLength("abc"))
// console.log(getLength([123, 321, 123]))