函数与类​

  • 2020-04-11

函数

JavaScript一样,TypeScript函数可以创建有名字的函数和匿名函数。 你可以随意选择适合应用程序的方式,不论是定义一系列API函数还是只使用一次的函数。

// Named function
function add(x, y) {
    return x + y;
}

// Anonymous function
let myAdd = function(x, y) { return x + y; };

函数声明方式

TypeScript能够根据返回语句自动推断出返回值类型,因此我们通常省略返回值类型声明.

  1. 直接声明函数参数, 直接在参数后面声明类型即可.
// 不申明
function add(x: number, y: number) {
   return x + y;
}

// 申明
function add(x: number, y: number): number {
    return x + y;
}
  1. 在实际开发中, 函数调用经常会直接使用解构赋值的方式, 进而减少赋值. 这种场景的声明方式如下:
function add({ x, y }: { x: number, y: number }) {
   return x + y;
}
add({ x: 2, y: 3 })
  1. 声明剩余参数

剩余参数在使用的时候, 实际是一个数组. 按照这个思路, 我们只需要声明数组格式即可.

function add(...rest: number[]) {
   return rest.reduce((pre, cur) => pre + cur)
}
add(2, 3, 4, 5)
add('23', 3) // 报错, 不能是字符串
  1. 在没有提供函数实现的情况下,有以下两种声明函数类型的方式:
// 1
type add = (x: number, y: number) => number;

// 2
interface add {
   (x: number, y: number): number
}

调用方式如下:

let addFn: add = (a, b) => {
   return a + b
}

函数声明常见错误

WARNING

必选参数不能位于可选参数后面. 可选参数必须位于所有必选参数后面.

// A required parameter cannot follow an optional parameter.
function add(x?: number, y: number) {
   return x + y;
}

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

let greeter = new Greeter("world");

类的修饰符扩展了原生JS 的一些功能特性,这个功能点非常好. 在日常使用中也特别特别多. 直接看代码.

  1. 公共,私有与受保护的修饰符.
class Father {
   constructor() { }

   public greet() {
       return "Hello";
   }

   private hello() {
       return 'ee';
   }

   protected hi() {
       return 'ee';
   }

}

class children extends Father {

   constructor() {
       super();
   }

   test() {
       this.hello(); // 报错: 是私有成员, 不可在类外部调用
       this.hi(); // 可调用
   }

}

new children().greet()

new children().hello() // 报错: 是私有成员, 不可在类外部调用

new children().hi() //报错: 只能在子类中调用
  1. 存取器

TypeScript支持通过 getters/setters 来截取对对象成员的访问。它能帮助你有效的控制对对象成员的访问。

class Greeter {
   constructor(message: string) {
       this.greeting = message;
   }
   greeting: string;
   get hello() {
       return this.greeting;
   }
   set hi(x) {
       this.greeting = x;
   }
}
const x = new Greeter('eeee')
x.hi('22');
x.hello = '2' // 报错, 不能修改

实际上就是使用getters/setters来截取对对象成员的访问。解析出来的源码如下:

var Greeter = /** @class */ (function () {
   function Greeter(message) {
       this.greeting = message;
   }
   Object.defineProperty(Greeter.prototype, "hello", {
       get: function () {
           return this.greeting;
       },
       enumerable: true,
       configurable: true
   });
   Object.defineProperty(Greeter.prototype, "hi", {
       set: function (x) {
           this.greeting = x;
       },
       enumerable: true,
       configurable: true
   });
   return Greeter;
}());
  1. 静态属性

static 它是一个不用 new 就可以直接调用的方法.

class Greeter {
   constructor() { }
   static config: string = '33';
}
Greeter.config = '3'

WARNING

若属性在 constructor 中声明可访问性了, 则不必在下面再声明一次.

class Dog {
   constructor(public name: string) {}
   name: string; // 报错, Duplicate identifier 'name'. 重复声明
   eat() { }
}
上次更新时间: 2020-04-11 18:18:00