Ts中对于函数类型函数写法的详细总结 函数重载

本文详细介绍了TypeScript中的函数类型声明,包括参数类型、返回值类型、箭头函数、类型别名、默认值、参数解构、rest参数、void类型、never类型以及函数重载和构造函数、async函数的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TypeScript 的函数类型

函数的类型声明,需要在声明函数时,给出参数的类型和返回值的类型。

// 写法一
function hello(text: string): void {
  console.log("hello " + text);
}
// 写法二
const hello: (text: string) => void = function (text) {
  console.log("hello " + text);
};
// 写法三:函数类型里面的参数名与实际参数名,可以不一致。 content / text
let fn: (content: string) => string;
fn = function (text: string) {
  return text;
};
// 写法四:常用
type MyFn = (text: string) => void;
const hello: MyFn = function (text) {
  console.log("hello " + text);
};
// 写法五: 非箭头函数类型
function hello(fn: (a: string) => void): void {
  fn("world");
}
// 写法六:初级不常见 可暂时省略 适用在函数本身存在属性的时候
let add: { (a: number, b: number): number };
add = function (a, b) {
  return a + b;
};

示例中,函数hello()在声明时,需要给出参数text的类型(string),及返回值的类型(void),此处void类型表示没有返回值

没有return语句,TypeScript 会推断出函数hello()没有返回值。

如果一个变量要套用另一个函数类型,有一个技巧,可以使用typeof运算符。

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

const myAddFn: typeof add = function (a, b) {
  return a + b;
};

例子

type Person = { name: string };
const arr = ["Jack", "Rose", "Peter"];
const people = arr.map((name): Person => ({ name }));

上面示例中,Person是一个类型别名,代表一个对象,该对象有属性name
map()方法的参数是一个箭头函数(name):Person => ({name}),该箭头函数的参数name的类型省略了,因为可以从map()的类型定义推断出来,箭头函数的返回值类型为Person。相应地,变量people的类型是Person[]
至于箭头后面的({name}),表示返回一个对象,该对象有一个属性name,它的属性值为变量name的值。这里的圆括号是必须的,否则(name):Person => {name}的大括号表示函数体,即函数体内有一行语句name,同时由于没有return语句,这个函数不会返回任何值。

参数默认值

设置默认值的参数,就是可选的。如果不传入该参数,它就会等于默认值。

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

上面示例中,参数ab的默认值都是0,调用add()时,这两个参数都是可以省略的。这里其实可以省略xy的类型声明,因为可以从默认值推断出来。

function add(a = 0, b = 0) {
  return a + b;
}

参数解构

函数参数如果存在变量解构,类型写法如下。

function add({ a, b, c }: { a: number; b: number; c: number }) {
  console.log(a + b + c);
}

参数解构可以结合类型别名(type 命令)一起使用

type ABC = { a: number; b: number; c: number };

function add({ a, b, c }: ABC) {
  console.log(a + b + c);
}

rest 参数

例子一:参数m就是 rest 类型,它的类型是一个数组。

function multiply(n: number, ...m: number[]) {
  return m.map((x) => n * x);
}

例子二:rest 参数可以与变量解构结合使用。

function repeat(...[str, times]: [string, number]): string {
  return str.repeat(times);
}

void 类型

void 类型表示函数没有返回值。

void 类型允许返回undefinednull
函数的运行结果如果是抛出错误,也允许将返回值写成void
!!!重点!!!

type voidFn = () => void;

const f: voidFn = () => {
  return 666;
};

这样使用并不会报错,但是如果使用这个函数的返回值,就会报错

type voidFn = () => void;

const f: voidFn = () => {
  return 666;
};

f() + 888; // 报错

never 类型

never类型表示肯定不会出现的值。它用在函数的返回值,就表示某个函数肯定不会返回值,即函数不会正常执行结束。

使用情景:
(1) throw error

function fail(msg: string): never {
  throw new Error(msg);
}

如果显式用return语句返回一个 Error 对象,返回值就不是 never 类型。
(2) 无限循环函数 省略

函数重载

说明: 一个函数可以接受不同类型或者数量的参数,根据参数的不同,会有不同的函数行为。
实现方法: 逐一定义每一种情况的类型。

Todo:
例子:

构造函数

例子:

// 第一种情况
class Animal {
  numLegs: number = 4;
}

type AnimalConstructor = new () => Animal;

function create(c: AnimalConstructor): Animal {
  return new c();
}

const a = create(Animal);

// 第二种情况  类型 F 就是一个构造函数
type F = {
  new (s: string): object;
};
// 第三种  F 既可以当作普通函数执行,也可以当作构造函数使用。
type F = {
  new (s: string): object;
  (n?: number): number;
};

async 函数

async 函数的的返回值是一个 Promise 对象。

const p: Promise<number> = 666;

async function fn(): Promise<number> {
  var i = await p;
  return i + 1;
}
<think>好的,用户现在问的是TypeScript中的constructor关键字。我需要先回顾一下之前的历史对话,看看用户之前问过什么问题,从而更好地理解他们的知识水平和需求。 之前用户问过关于TS中let关键字的问题,我详细解释了let的作用域、变量重新声明、类型标注、暂时性死区以及编译结果。用户可能现在在学习TypeScript的基础,特别是关于类和相关概念。constructor是类中的一个重要部分,所以用户可能在尝试理解如何创建和使用类,或者遇到相关的代码示例需要解释。 接下来,我需要确定用户的具体需求。他们可能想了解constructor的基本用法,如何初始化对象,或者与JavaScript中的constructor有什么区别。另外,用户可能对TypeScript特有的功能,如参数属性修饰符(public、private等)感兴趣,或者在使用constructor时遇到问题,比如类型检查或继承相关的问题。 我需要确保回答覆盖以下几个方面: 1. constructor的基本定义和作用。 2. 在TypeScript中constructor与JavaScript的区别,特别是参数属性和访问修饰符。 3. 构造函数的类型标注和重载。 4. 继承中的super调用。 5. 与普通函数的区别。 6. 实际使用场景的例子。 另外,用户可能需要一些示例代码来更好地理解这些概念。之前回答let的时候用了代码示例,这次也应该保持一致性,提供清晰的例子。 还需要注意用户可能的误区,比如在JavaScript中,构造函数可以不用class语法,但在TypeScript中通常使用class。同时,TypeScript的constructor参数属性可能对新手来说比较陌生,需要详细解释。 检查是否有其他需要注意的点,比如编译后的代码是怎样的,或者与接口、泛型的结合使用,但考虑到用户当前的问题可能更基础,暂时不需要深入这些高级主题,但可以简要提及。 最后,确保回答结构清晰,逐步解释,帮助用户逐步理解constructor关键字在TypeScript中的使用和特点。</think>在 TypeScript 中,`constructor` 关键字是用于定义**类构造函数**的特殊方法。以下是逐步解析: --- ### 1. **核心作用** - **对象初始化**:当通过 `new` 创建类实例时自动调用 - **属性赋值**:主要用于初始化类成员变量 - **参数接收**:允许传递初始值给类的实例 基础示例: ```typescript class Person { name: string; age: number; // 构造函数 constructor(name: string, age: number) { this.name = name; this.age = age; } } const alice = new Person("Alice", 30); // 触发构造函数 ``` --- ### 2. **TypeScript 特有功能** #### ▸ **参数属性修饰符** (Parameter Properties) - 直接在构造函数参数中声明类属性 - 支持 `public`/`private`/`protected`/`readonly` 修饰符 简化写法: ```typescript class Student { // 等价于声明属性 + 自动赋值 constructor( public id: number, private course: string ) {} } const stu = new Student(1001, "Math"); console.log(stu.id); // 1001(public可访问) console.log(stu.course); // 报错(private不可访问) ``` --- ### 3. **类型标注与重载** #### ▸ **构造函数类型** - 通过 `new` 关键字定义构造签名 ```typescript interface AnimalConstructor { new (name: string): Animal; } class Animal { constructor(public name: string) {} } function createAnimal(ctor: AnimalConstructor, name: string) { return new ctor(name); } ``` #### ▸ **构造函数重载** - 支持通过不同参数组合初始化对象 ```typescript class Vector { x: number; y: number; // 重载声明 constructor(); constructor(x: number, y: number); // 实现签名 constructor(x?: number, y?: number) { this.x = x ?? 0; this.y = y ?? 0; } } const v1 = new Vector(); // (0,0) const v2 = new Vector(3,4); // (3,4) ``` --- ### 4. **继承中的 super()** - 派生类必须通过 `super()` 调用父类构造函数 - 必须在访问 `this` 之前调用 继承示例: ```typescript class Employee extends Person { department: string; constructor(name: string, age: number, department: string) { super(name, age); // 必须首先调用 this.department = department; } } ``` --- ### 5. **与普通函数的区别** | 特性 | 构造函数 | 普通函数 | |---------------------|---------------------------|--------------------------| | 调用方式 | 必须通过 `new` 调用 | 直接调用 | | 返回值 | 隐式返回实例对象 | 可返回任意值 | | `this` 指向 | 指向新创建的实例 | 严格模式为 `undefined` | | 原型链 | 自动关联 `prototype` | 无自动关联 | --- ### 6. **典型使用场景** - 初始化对象状态 - 依赖注入(通过参数传递外部资源) - 实现工厂模式 - 构建不可变对象(配合 `readonly`) ```typescript class ImmutablePoint { constructor( public readonly x: number, public readonly y: number ) {} } const p = new ImmutablePoint(5, 5); p.x = 10; // 编译错误:readonly属性 ``` --- ### 编译结果观察 当编译为 ES6 时: ```javascript class Person { constructor(name, age) { this.name = name; this.age = age; } } ``` 当编译为 ES5 时: ```javascript var Person = /** @class */ (function () { function Person(name, age) { this.name = name; this.age = age; } return Person; }()); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值