主要介绍函数类型、用接口表示数组、类数组

函数的类型

在JS中,有两种定义函数的方式:

  1. 函数声明(Function declaration)
  2. 函数表达式(Function expression)
  1. // 函数声明
  2. function sum(x, y) {
  3. return x + y
  4. }
  5. // 函数表达式
  6. let mySum = function(x, y) {
  7. return x + y
  8. }

ts函数声明

对函数的参数,返回值进行约束,参数多或少都是不允许的

  1. function sum(x: number, y: number): number {
  2. return x + y
  3. }
  4. sum(1, 2)
  5. sum(1, 2, 3) // Error
  6. sum(1) // Error

ts函数表达式

  1. let mySum = function (x: number, y: number): number {
  2. return x + y
  3. }
  4. // 规范写法 ts的类型定义中,=> 用来表示函数的定义,左边是输入类型、需要用括号括起来,右边是输出类型
  5. let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
  6. return x + y
  7. }

用接口定义函数形状

  1. interface SearchFunc {
  2. // 接口里面的函数类型
  3. (source: string, subString: string): boolean;
  4. }
  5. let mySearch: SearchFunc;
  6. mySearch = function(source: string, subString: string) {
  7. return source.includes(subString)
  8. }

可选参数

函数的可选参数必须要在必选参数后面,如果可选参数放前面,会提示错误

  1. function buildName(firstName: string, lastName?: string) {
  2. return lastName ? `${firstName} ${lastName}` : firstName
  3. }
  4. let tomcat = buildName('Tom', 'Shu');
  5. let tom = buildName('Tom');

参数默认值

如果指定了默认参数,该参数即成为可选参数,且没有可选参数位置的限制

  1. function buildName(firstName: string = 'Tom', lastName: string) {
  2. return firstName + ' ' + lastName;
  3. }
  4. let tomcat = buildName('Tom', 'Cat');
  5. let cat = buildName(undefined, 'Cat');

剩余参数

与es6一样,剩余参数只能是最后一个参数

  1. function push(array, ...items) {
  2. items.forEach(item => array.push(item))
  3. }
  4. let a = []
  5. push(a, 1, 2, 3) // items [1, 2, 3]
  6. // typescript 约束
  7. function push(array: any[], ...items: any[]) {
  8. items.forEach(item => array.push(item))
  9. }

重载

函数重载是指允许同时定义几个名称相同的函数(但参数个数、类型、返回值可能会不一样),一般js里后面定义的函数会直接覆盖前面的函数

例子:实现一个函数reverse,输入数字123时,输出321,输入字符串’hello’时,输出反转字符串 ‘olleh’

  1. // 普通联合类型实现
  2. function reverse(x: number | string): number | string {
  3. if (typeof x === 'number') {
  4. return Number(x.toString().split('').reverse().join(''))
  5. } else if (typeof x === 'string') {
  6. return x.split('').reverse().join('')
  7. }
  8. }
  9. // 联合类型缺点:表达不够精确,输入数字的时候,输出应该也是数字,输入字符串的时候,输出也为字符串
  10. // 可以用函数重载,定义多个reverse函数
  11. // 前两次是函数定义,最后一次是函数实现。ts会优先匹配最前面的,再匹配的后面的
  12. function reverse(x: number): number;
  13. function reverse(x: string): string;
  14. function reverse(x: number | string): number | string {
  15. if (typeof x === 'number') {
  16. return Number(x.toString().split('').reverse().join(''))
  17. } else if (typeof x === 'string') {
  18. return x.split('').reverse().join('')
  19. }
  20. }

用接口表示数组

NumberArray 表示:只要索引的类型是数字时,那么值的类型必须是数字。除了类数组外,一般都不使用这种方式

  1. interface NumberArray {
  2. [index: number]: number
  3. }
  4. let array: NumberArrray = [1, 1, 2, 3, 5]

类数组

类数组不是数组类型,需要用接口来描述类数组

  1. // arguments 实际是一个类数组,但赋值给数组类型的变量会报错
  2. function sum() {
  3. let args: number[] = arguments // Error
  4. }
  5. // 用接口来描述类数组
  6. function sum() {
  7. let args: {
  8. [index: number]: number;
  9. length: number;
  10. callee: Function;
  11. } = arguments
  12. }
  13. interface IArguments {
  14. [index: number]: number;
  15. length: number;
  16. callee: Function;
  17. }
  18. function sum() {
  19. let args: IArguments = arguments;
  20. }