在 TypeScript 里,我们可以通过 function 字面量和箭头函数的形式定义函数,如下所示:

function add() {}
const add = () => {}

还可以显式指定函数参数和返回值的类型,如下所示:

const add = (a: number, b: number): number => {
  return a + b;

如上述示例中,参数名后的 :number 表示参数类型都是数字类型,圆括号后的 : number则表示返回值类型也是数字类型。下面介绍一下返回值类型和参数类型

返回值类型

在 JavaScript 中,如果一个函数可以没有显式 return,此时函数的返回值是 undefined:

function func() {
  ......
console.log(func()); // undefined

需要注意的是,在 TypeScript 中,如果我们显式声明函数的返回值类型为 undfined,会报错:

function fn(): undefined { 
// error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
 ......

此时,正确的做法是使用void 类型来表示函数没有返回值的类型(void 类型很少用到,这基本是唯一有用的场景),示例如下:

function func(): void {
  ......
func().someFunc(); // error TS2339: Property 'someFunc' does not exist on type 'void'.

我们可以使用类似定义箭头函数的语法来表示函数类型的参数返回值类型,此时 => 仅仅用来定义一个函数类型而不是实现这个函数。

需要注意的是,这里的 =>与 ES6 中箭头函数的 => 有所不同。TypeScript 函数类型中的 => 用来表示函数的定义,其左侧是函数的参数类型,右侧是函数的返回值类型;而 ES6 中的 => 是函数的实现。

如下示例中,先定义了一个函数类型(这里使用了类型别名 type),并且使用箭头函数实现了这个类型:

type Adder = (a: number, b: number) => number; // TypeScript 函数类型定义
const add: Adder = (a, b) => a + b; // ES6 箭头函数

在对象中,除了使用这种声明语法,我们还可以使用类似对象属性的简写语法来声明函数类型的属性,如下代码所示:

interface Entity {
  add: (a: number, b: number) => number;
  del(a: number, b: number): number;
const entity: Entity = {
  add: (a, b) => a + b,
  del(a, b) {
    return a - b

在某种意义上来说,这两种形式都是等价的。但是很多时候,我们不必或者不能显式地指明返回值的类型,这就涉及可缺省可推断的返回值类型

可缺省和可推断的返回值类型

函数返回值的类型可以在 TypeScript 中被推断出来,即可缺省

函数内是一个相对独立的上下文环境,我们可以根据入参对值加工计算,并返回新的值。从类型层面看,我们也可以通过类型推断加工计算入参的类型,并返回新的类型,如下所示:

function func(one: string, two: number) {
  const nums = [two];
  const strs = [one];
  return {
    nums,
  } // 返回 nums: number[]; strs: string[] 的类型

了解了定义函数的基本语法以及返回值类型后,再来详细看一下可选参数默认参数剩余参数的几个特性。

可选参数和默认参数

在实际工作中,我们可能经常碰到函数参数可传可不传的情况,当然 TypeScript 也支持这种函数类型表达,如下代码所示:

function func(x?: string) {
  return x;
func(); // undefined
func('777'); // 777

在上述代码中,我们在类型标注的 : 前添加 ? 表示 func 函数的参数 x 是可缺省的

也就是说参数 x 的类型可能是 undefined(不传入实参)类型或者是 string 类型(传入 ‘777’ 实参),那是不是意味着可缺省和类型是 undefined 等价呢?

function func1(x?: string) {
  console.log(x);
function func2(x: string | undefined) {
  console.log(x);
func1(); // undefined
func1(undefined); // undefined
func2(); // error TS2554: Expected 1 arguments, but got 0.
func2(undefined); // undefined

这里的 ?: 表示参数可以缺省、可以不传,也就是说调用函数时,我们可以不显式传入参数。但是,如果我们声明了参数类型为 xxx | undefined,就表示函数参数是不可缺省且类型必须是 xxx 或者 undfined

因此,在上述代码中,func2 函数如果不显示传入函数的参数,TypeScript 就会报一个 ts(2554) 的错误,即函数需要 1 个参数,但是我们只传入了 0 个参数。

在 ES6 中支持函数默认参数的功能,而 TypeScript 会根据函数的默认参数的类型来推断函数参数的类型,示例如下:

function func(x = '777') {
  console.log(x);
func(); // 777
func('hello world') // hello world
func(1); // error TS2345: Argument of type '1' is not assignable to parameter of type 'string | undefined'.

在上述示例中,根据函数的默认参数 ‘777’ ,TypeScript 推断出了 x 的类型为 string | undefined

在 ES6 中,JavaScript 支持函数参数的剩余参数,它可以把多个参数收集到一个变量中。同样,在TypeScript 中也支持这样的参数类型定义,如下代码所示:

function sum(...nums: number[]) {
  return nums.reduce((a, b) => a + b, 0);
sum(1, 2); // 3
sum(1, 2, 3); // 6
sum(1, '2'); // error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

在上述代码中,sum 是一个求和的函数,...nums 将函数的所有参数收集到了变量 nums 中,而 nums 的类型应该是 number[],表示所有被求和的参数是数字类型。因此,sum(1, ‘2’) 抛出了一个 ts(2345) 的错误,因为参数 ‘2’ 并不是 number 类型。

如果这么写就可以:

function sum(...nums: (number | string)[]): number {
  return nums.reduce<number>((a, b) => a + Number(b), 0);
sum(1, '2'); // 3

函数的每一个参数的类型就是联合类型 number | string,因此 sum(1, ‘2’, 3) 的类型检查也就通过了。

众所周知,在 JavaScript 中,函数 this 的指向一直是一个令人头痛的问题。因为 this 的值需要等到函数被调用时才能被确定,更别说通过一些方法还可以改变 this 的指向。也就是说 this 的类型不固定,它取决于执行时的上下文。

但是,使用了 TypeScript 后,我们就不用担心这个问题了。通过指定 this 的类型(严格模式下,必须显式指定 this 的类型),当我们错误使用了 this,TypeScript 就会提示我们,如下代码所示:

function func() {
 console.log(this.name); // error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.
func();

在上述代码中,如果我们直接调用 say 函数,this 应该指向全局 window 或 global(Node 中)。但是,在 strict 模式下的 TypeScript 中,它会提示 this 的类型是 any,此时就需要我们手动显式指定类型了。

在 TypeScript 中,我们只需要在函数的第一个参数中声明 this 指代的对象(即函数被调用的方式)即可,比如最简单的作为对象的方法的 this 指向,如下代码所示:

function func(this: Window, name: string) {
  console.log(this.name);
window.func = func;
window.func('hello');
const obj = {
obj.func('hello'); // error TS2684: The 'this' context of type '{ func: (this: Window, name: string) => void; }' is not assignable to method's 'this' of type 'Window'.

在上述代码中,我们在 window 对象上增加 say 的属性为函数 say。那么调用 window.say() 时,this 指向即为 window 对象。

调用 obj.say() 后,此时 TypeScript 检测到 this 的指向不是 window,于是抛出了如下所示的一个 ts(2684) 错误。

需要注意的是,如果我们直接调用 func(),this 实际上应该指向全局变量 window,但是因为 TypeScript 无法确定 func 函数被谁调用,所以将 this 的指向默认为 void,也就提示了一个 ts(2684) 错误。 如下所示:

func('777'); // error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Window'.

此时,我们可以通过调用 window.say() 来避免这个错误,这也是一个安全的设计。因为在 JavaScript 的严格模式下,全局作用域函数中 this 的指向是 undefined。

同样,定义对象的函数属性时,只要实际调用中 this 的指向与指定的 this 指向不同,TypeScript 就能发现 this 指向的错误,示例代码如下:

interface Person {
  name: string;
  say(this: Person): void;
const person: Person = {
  name: 'Jae',
  say() {
    console.log(this.name);
const func = person.say;
func(); // error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Person'.

JavaScript 是一门动态语言,针对同一个函数,它可以有多种不同类型的参数与返回值,这就是函数的多态

而在 TypeScript 中,也可以相应地表达不同类型的参数和返回值的函数,如下所示:

function convert(x: string | number | null): string | number | -1 {
  if (typeof x === 'string') {
    return Number(x);
  if (typeof x === 'number') {
    return String(x);
  return -1;
const x1 = convert('1'); // => string | number
const x2 = convert(1); // => string | number
const x3 = convert(null); // => string | number

在上述代码中,我们把 convert 函数的 string 类型的值转换为 number 类型,number 类型转换为 string 类型,而将 null 类型转换为数字 -1。此时, x1、x2、x3 的返回值类型都会被推断成 string | number

那么,有没有一种办法可以更精确地描述参数与返回值类型约束关系的函数类型呢?有,这就是函数重载。如下示例中先定义了三种各不相同的函数类型列表,并描述了不同的参数类型对应不同的返回值类型,而后才是函数的实现:

function convert(x: string): number;
function convert(x: number): string;
function convert(x: null): -1;
function convert(x: string | number | null): any {
  if (typeof x === 'string') {
      return Number(x);
  if (typeof x === 'number') {
      return String(x);
  return -1;
const x1 = convert('1'); // => number
const x2 = convert(1); // => string
const x3 = convert(null); // -1

类型谓词(is)

在 TypeScript 中,函数还支持另外一种特殊的类型描述,如下示例 :

function isString(s: unknown): s is string {
  return typeof s === 'string';
function isNumber(n: number) {
  return typeof n === 'number';
function func(x: unknown) {
  if (isString(x)) {...} // 没问题
  if (isNumber(x)) {...} // error TS2345: Argument of type 'unknown' is not assignable to parameter of type 'number'.

在上述代码中,在添加返回值类型的地方,通过“参数名 + is + 类型”的格式明确表明了参数的类型,进而引起类型缩小,所以类型谓词函数的一个重要的应用场景是实现自定义类型守卫

仅使用TypeScript类型系统实现的函数和算法 的类型系统使我们可以在编写代码时捕获代码中的错误和错误,而不是稍后再运行代码。 但是...那是使用类型系统的明显方式... :winking_face_with_tongue: 这个项目试图通过实际上在各种类型系统之上实现各种功能和算法,将TypeScript类型系统推向极限。 每个实现都包含详细描述正在发生的事情的注释。 一些功能和算法使用创造性的(有时是没有官方支持的)解决方案来克服类型系统的。 :index_pointing_up: 请注意,该项目仅用于娱乐和学习目的,并非用于实际用途。 尝试运行代码 首先安装依赖项: $ yarn 打开任何函数或算法的文件,将鼠标悬停在类型上,以查看通 参考的gitbook 其实TS用的很多东西跟ES6是高度重合的,包括箭头函数/解构赋值/模块/类的部分特性 不重合的是类型声明 接口的灵活实现 还有一些补充的 关键字/抽象类/函数重载/泛型 写了一些语法demo,供大家研究 如果你是一名在行人员 强烈建议阅读英语,以获取第一手资料 目前本仓库没增加编译工具,仅是研究了一下TS的语法 欢迎加我微信交流(微信名:kashao3824) 学习todo的写法 使用browser-sync来托管静态服务器 (npm run serve看效果) 添加了中划线样式 添加了全部完成功能 添加了删除功能 译者 | 禾木木 责编 | 夏萌出品 | CSDN(ID:CSDNnews)近日,微软宣布正式发布 TypeScript 5.1版本。如果你还不熟悉 TypeScript,它是一种建立在 JavaScript 基础上的语言,通过添加静态类型语法来构建的语言。这些类型可以描述我们程序的一些细节,可以使用 TypeScript 对代码进行类型检查,并在运行代码之前告诉你代码错误的相关信息。... npm install typescript-collections --save ES6 import ... from import * as Collections from 'typescript-collections' ; 或 TypeScript import ... require import Collections = require ( 'typescript-collections' ) ; 或 JavaScript va 学习打字稿 这只是我正在学习的一件事。 静态类型检查。 可以转换为JavaScript的CLI工具,该JavaScript也可以在较旧的浏览器上运行。 也可以使用构造函数参数public关键字作为速记,以自动向类添加属性。 我想我真的很喜欢TypeScript的interface和enum部分(例如,作为可参考的代码内参考,可帮助您/其他人记住要包含或可选包含的输入)。 为什么要打扰类型:对我来说,类型检查不仅用于防止错误,而且还提醒您需要实现哪些数据或功能。 就像自动生成的文档一样。 在浏览器中实时尝试 官方网站的游乐场: : 使用CLI在本地尝试 npm install -g typescript tsc code-to-compile.ts tsc code-to-compile.ts --outDir output tsc code-to-comp 1、函数表达式方式:let isPrime: (n: number) =&gt; boolean = n =&gt; { //body }2、函数声明方式:function isPrime (n: number):boolean { //body }3、如果需要在对象字面量里面定义方法:let math = { squareRoot(n:number):number { //.... 目录本文概览:1. 函数类型(1)为函数定义类型(2)完整的函数类型(3)使用接口定义函数类型(4)使用类型别名2. 函数参数(1)可选参数(3)默认参数(3)剩余参数3. 函数重载 本文概览: 1. 函数类型 (1)为函数定义类型 我们可以给函数定义类型,这个定义包括对参数和返回值的类型定义: function add(arg1: number, arg2: number): number { return x + y; const add = (arg1: number, arg2: num 本文介绍了TS 中有关函数的知识,包括函数的声明方式,如何声明函数类型函数参数和返回值的类型函数重载以及 this 的类型。大部分内容和 JS 中差不太多,主要是 this 类型函数重载这两点,需要额外关注下。 一、TS类型注解 一种为变量添加类型约束的形式,(什么类型的变量,赋值什么类型的数据,否则会报错) 语法类型:var/let/const 变量名:数据类型=值 number和Number的区别? 虽说在声明的时候,并不会进行报错,但是在设置数据类型注解的时候,尽量使用小写,大部分基本数据类型都是小写的,Number一般代表的是一个类 ts中的变量的声明,注意变量名是否重复 在ts中使用let声明的变量,会在全局的文件中进行查找,如果有重复的,该变量的声明就会报错(有波浪线),所以在ts文件中底部 expor 函数同样是TypeScript的基础之一。通过函数你可以将重合的功能代码块进行封装,然后在你需要它的时候调用即可。换句话说函数就是具有某一功能的代码块,它的使命是将你臃肿的代码变的更加苗条。 首先,咱们先来回顾一下之前在JS中是如何创建函数以及实现调用的: 1、函数声明: function fn (a,b){ return a + b; 2、函数表达式: let fn = fun... 函数TypeScript应用程序的基础。它帮助你实现抽象层,模拟类,信息隐藏和模块。在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义行为的地方。 一、函数 TypeScript函数可以创建有名字的函数和匿名函数,例如: function add(x,y){ return x+y; //匿名函数 let myAdd = function(x,y){return x + y;}; 函数可以使用外部变量,称为捕获了这些变量。 let z =.. 错误信息列表code类型英文描述中文描述1002错误Unterminated string literal.未终止的字符串文本。1003错误Identifier expected.应为标识符。1005错误'{0}' expected.应为“{0}”。1006错误A file cannot have a reference to itself.文件不能引用自身。1009错误Trailing comm...