TypeScript 函数function

ts的函数是js函数的超集,在原有功能基础上增加了,类型系统支持,让函数更安全,更可维护,更易于重构。

1.基本语法:函数生命与类型注解

函数声明:带参数类型和返回值类型

ts 复制代码
// 函数声明:带参数类型和返回值类型
// function add(...):定义一个叫 add 的函数。
// (a: number, b: number):这个函数接受两个参数,a 和 b,它们都必须是 数字类型(number)。
// : number:表示这个函数的返回值也必须是 数字类型。
// { return a + b; }:函数体,把 a 和 b 相加后返回。

function add(a: number, b: number): number {
    return a + b;
}

// 函数表达式
const greet = function(name: string): string {
    return "Hello, " + name;
};

// 箭头函数(推荐)
const multiply = (x: number, y: number): number => x * y;
关键点:

参数必须声明类型:a: number
返回值类型可省略(TS 会自动推断),但建议显式写出
箭头函数更简洁,适合回调

greet("小刘")
console.log(greet("小刘"))
//打印结果: Hello,小刘
2.可选参数与默认参数

可选参数:用 ? 表示

ts 复制代码
// 可选参数:用 ? 表示
//定义一个logMessage的函数,message,userId参数userId?表示用户id可以传也可以不传 。
function logMessage(message: string, userId?: string): void {
	//`${...}`:这是 JavaScript 的模板字符串,可以插入变量。
	// userId ?? 'Anonymous':这是"空值合并操作符"
	// 意思是:如果 userId 是 null 或 undefined(没传),就用 'Anonymous'(匿名)代替。
	// 如果传了 userId,就用传的值。
    console.log(`[${userId ?? 'Anonymous'}] ${message}`);
}

logMessage("Hello");                  
logMessage("Hello", "user123"); 
3.剩余参数

...numbers 是 TypeScript/JavaScript 中一个非常强大又常用的特性,叫做 剩余参数(Rest Parameters)

ts 复制代码
3.剩余参数(Rest Parameters)
// ...numbers 是 TypeScript/JavaScript 中一个非常强大又常用的特性,叫做 剩余参数(Rest Parameters)。
// ...numbers:意思是"把所有剩下的参数收集到一个叫 numbers 的数组里"
// : number[]:说明这个数组里的每一项都必须是 数字
// 合起来:...numbers: number[] → "接收任意多个数字,把它们放进一个数组"
function sum(...numbers: number[]): number {
    return numbers.reduce((acc, n) => acc + n, 0);
}

sum(1, 2);        // 3
sum(1, 2, 3, 4);  // 10
// ...numbers 必须是最后一个参数
// 为什么 ...numbers 必须是最后一个参数?
// 这是 JavaScript 语言的硬性规则:
// 剩余参数(...)必须放在参数列表的最后,不能有参数跟在它后面。
4.函数重载

同一个函数名,可以根据你传的不同参数,表现出不同的行为,并且有对应的类型提示。 像一个多面手函数,能根据情况自动切换模式。

ts 复制代码
// 为同一个函数提供多个类型定义,用于不同参数组合。

// 重载签名(没有函数体)
// 重载签名 1:当传两个字符串时,返回 string
function combine(a: string, b: string): string;
// 重载签名 2:当传两个数字时,返回 number
function combine(a: number, b: number): number;

// 实现签名(有函数体,类型最宽)(真正干活的)
function combine(a: any, b: any): any {
    return a + b;
}

combine("Hello", "World");  // 返回 string
combine(1, 2);              // 返回 number
// combine(1, "2");         // 错误!没有匹配的重载
// 用途:提高类型安全性,让编辑器知道不同调用方式的返回类型
5.类型别名定义函数签名

type是TypeScript 中一个非常优雅的特性:使用 type 定义函数类型,并用它来约束函数的结构。

ts 复制代码
//定义一个类型别名GreetingFunction,描述这个函数要接收两个参数,name和language可传可不传。
type GreetingFunction = (name: string, language?: string) => string;

//定义一个greetEnglish常量(函数)。 
// : GreetingFunction类型注解  表示这个函数必须符合我们上面定义的规则。
// (name) => ...:箭头函数,只传了 name,language 没用到(可选,所以可以不传)
const greetEnglish: GreetingFunction = (name) => `Hello, ${name}`;
const greetChinese: GreetingFunction = (name) => `你好, ${name}`;

greetEnglish("Alice");     // 返回 "Hello, Alice"
greetChinese("小明");      // 返回 "你好, 小明"
// 适合定义回调函数、事件处理器等。
6.泛型函数

让函数支持多种类型,同时保持类型安全。优势:复用性强,类型不丢失

ts 复制代码
//identity是一个函数,它接收一个参数arg,并原样返回它。(恒等函数)
// <T> 是泛型的语法:T 是一个类型参数(type parameter),它是一个占位符,代表将来会被指定的具体类型。
// arg: T 表示参数 arg 的类型是 T。
// : T 表示函数的返回值类型也是 T。
// 这个函数保证了输入的类型和输出的类型是一致的。
// 这个函数保证了输入的类型和输出的类型是一致的。
function identity<T>(arg: T): T {
    return arg;
}

// 这里显式地告诉 TypeScript:T 是 string。
// 所以 arg 必须是 string 类型,返回值也是 string 类型。
// 虽然 "hello" 明显是字符串,但你可以强制指定类型。
identity<string>("hello");  // 显式指定 T 为 string
// 这里没有写 <number>,TypeScript 自动推断(type inference) 出 T 是 number,因为传入的是 42。
// 这是泛型的常见用法:省略类型参数,让编译器自动推断。
identity(42);               // 自动推断 T 为 number

// 泛型数组
// 这个函数用于反转一个数组。
// items: T[] 表示传入一个元素类型为 T 的数组。
// 返回值是 T[],即类型为 T 的数组。
// slice() 创建原数组的浅拷贝,reverse() 反转这个拷贝,避免修改原数组。
function reverse<T>(items: T[]): T[] {
    return items.slice().reverse();
}

const numbers = [1, 2, 3];
const reversedNumbers = reverse(numbers);
// reversedNumbers: number[],值为 [3, 2, 1]

const words = ["a", "b", "c"];
const reversedWords = reverse(words);
// reversedWords: string[],值为 ["c", "b", "a"]
7.this 类型注解

显示指定this的类型 (尤其在回调中)

ts 复制代码
// 显式指定 this 的类型(尤其在回调中)
//定义一个handle的类
//它有一个实例属性data,默认值为"hello"
class Handler {
    data = "hello";

    // 错误:普通函数中 this 可能丢失
	// 这里使用了 函数表达式 赋值给实例属性。
	// 问题在于:当这个函数被用作事件处理器(比如 button.addEventListener('click', handler.onButtonClick_bad))时,
	// this 不再指向 Handler 实例,而是取决于如何被调用。
	// 在严格模式下(TypeScript 默认开启),this 会是 undefined,导致 this.data 报错(Cannot read property 'data' of undefined)。
	// 原因:JavaScript 中 this 的值由调用方式决定,而不是定义位置。
    onButtonClick_bad = function(e) {
        // console.log(this.data); //运行时 this 可能是 undefined
    }

    // 正确:箭头函数自动绑定 this
	// 箭头函数 不会创建自己的 this,而是继承外层作用域的 this。
	// 在类中,这个外层作用域就是类的构造函数或实例,因此 this 始终指向当前的 Handler 实例。
	// 无论这个函数被如何调用(比如作为事件处理器),this.data 都能正确访问。
	// 这是现代 TypeScript/JavaScript 中最常用、最推荐的写法。

    onButtonClick_good = (e) => {
        console.log(this.data); //  正确输出 "hello"
    }

    // 或者显式注解 this 类型
	// 这是一个普通方法,但第一个参数名为 this,类型为 Handler。
	// 这是 TypeScript 的特殊语法:显式声明该方法中 this 的类型。
	// TypeScript 会检查:只有当这个方法被 Handler 实例调用时才合法。
	//例如
	const handler = new Handler();
	handler.onClick(e); // 正确:this 指向 handler
	
	
    onClick(this: Handler, e: Event) {
        console.log(this.data); // 必须通过 Handler 实例调用
    }
}
8.函数类型表达式(function type)

直接定义函数的"类型"

ts 复制代码
//声明了一个变量 myFunc,指定了它的类型。
//类型是 (a: number, b: string) => boolean;它表示这个函数接受两个参数。
//第一个参数是a和第二个参数是b.
//它返回一个boolean类型(true or false)
let myFunc: (a: number, b: string) => boolean;

//函数赋值
//第一个参数:number	x --- 虽然没写类型,但根据上下文,TypeScript 会推断它是 number
//第二个参数:string	y --- 同样,TypeScript 推断它是 string
//返回值:boolean	return y.length > x --- 比较操作的结果是 true 或 false,即 boolean
myFunc = function(x, y) {
	//y 是字符串(string),所以 y.length 是它的字符长度(一个数字)。
	// x 是一个数字(number)。
	// 这个表达式判断:字符串 y 的长度是否大于数字 x。
	// 返回 true 或 false。
    return y.length > x;
}; 
9.构造函数类型(newable)

表示可以被 new 调佣的函数(即类或构造函数)

ts 复制代码
表示可以被 new 调用的函数(即类或构造函数)
//定义函数createInstance
//参数ctor: { new(): object }
// { new(): object }是一个对象类型字面量,表示"具有构造函数签名的对象"
//new() 表示:这个对象可以被 new 调用(即它是一个类或构造函数)。
//(): object 表示:调用 new 时不需要参数(空括号),并返回一个 object 类型的实例。
//所以,ctor 的类型是一个"无参构造函数,返回一个对象"。
function createInstance(ctor: { new(): object }): object {
	
	//函数体:return new ctor();
	// 使用 new 调用传入的构造函数 ctor,创建一个新实例并返回。
	// 因为类型系统知道 ctor 是可构造的,所以 new ctor() 是合法的。
	返回类型:: object
	表示函数返回一个对象(任何对象)。
	在实际使用中,返回的其实是 ctor 所代表类的实例。
    return new ctor();
}

//定义了一个简单的类 MyClass。
// 它没有构造函数,因此默认有一个无参构造函数。
// 它的实例是一个空对象(但属于 MyClass 类型)。
class MyClass {}
// 把 MyClass 这个类本身(而不是实例)作为参数传给 createInstance。
// MyClass 是一个构造函数,可以被 new 调用,且无参数,符合 { new(): object } 的类型。
// 函数内部执行 new MyClass(),创建一个 MyClass 的实例并返回。
// 调用成功,返回一个 MyClass 的实例。
//虽然 createInstance 的返回类型是 object,你可能需要类型断言才能访问 name 属性(见下文改进)。
createInstance(MyClass);
相关推荐
又写一个小bug16 分钟前
如何让你的Vue项目支持局域网访问 - 完整指南
前端
walking95720 分钟前
前端开发中常用的JavaScript方法
前端·面试
大舔牛23 分钟前
图片优化全景策略
前端·面试
卸任34 分钟前
阿里云域名迁移到Cloudflare DNS管理
前端·dns
谢小飞44 分钟前
Echarts高级柱状图开发:渐变与3D效果实现
前端·echarts
FogLetter1 小时前
Vite vs Webpack:前端构建工具的双雄对决
前端·面试·vite
tianchang1 小时前
JS 排序神器 sort 的正确打开方式
前端·javascript·算法
怪可爱的地球人1 小时前
ts的类型兼容性
前端
方圆fy1 小时前
探秘Object.prototype.toString(): 揭开 JavaScript 深层数据类型的神秘面纱
前端