• TS快速入门-函数


    在TS里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义行为的地方

    TS中的函数大部分和JS相同,不同之处在于ts会给函数返回值和参数加上类型声明

    在TS中,函数仍然是最基本、最重要的概念之一

    函数类型定义

    函数类型的定义包括对参数返回值的类型定义

    1. 直接定义函数类型

    function sayMyself(name: string, age: number): string {
        return `我是${name},我今年${age}`;
    }
    
    const sayMyself = (name: string, age: number) => {
        return `我是${name},我今年${age}`;
    }
    
    console.log(sayMyself('温情key', 23));  // 我是温情key,我今年23岁
    
    function printMsg(warn: string): void {
        console.warn('警告信息', warn);
    }
    
    const printMsg = (warn: string): void => {
        console.warn('警告信息', warn);
    }
    
    printMsg('警告警告123');  // 警告信息 警告警告123
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    如果在这里省略参数的类型,TypeScript 会默认这个参数是 any 类型;

    如果省略返回值的类型
    要是函数无返回值,那么 TypeScript 会默认函数返回值是 void 类型;
    要是函数有返回值,那么 TypeScript 会根据定义的逻辑推断出返回类型。

    2. type定义函数类型

    /* 先利用type声明一个函数 */
    type Submit = (user: string, props: object) => string;
    
    /* 再根据函数的声明实现函数 */
    const submitHandle: Submit = (user, props) => {
        return `提交成功, ${user}`
        // return 123     // 返回一个数字会报错,错误信息如下
        // 不能将类型“(user: string, props: object) => number”分配给类型“Submit”。  不能将类型“number”分配给类型“string”。
    }
    
    submitHandle('温情key', { age: 22 });
    // submitHandle(123, { age: 22 });  // error   类型“number”的参数不能赋给类型“string”的参数。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3. interface定义函数类型

    使用接口可以清晰地定义函数类型

    interface AddInt {
        (x: number, y: number): number;
    }
    
    const add: AddInt = (a, b) => {
        return a + b
    }
    
    
    //  不能将类型“(a: number, b: number) => string”分配给类型“AddInt”。
    //  不能将类型“string”分配给类型“number”。
    // const add: AddInt = (a: number, b: number) => {
    //     return 'wwww'
    // }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    函数参数定义

    1. 可选参数

    可选参数的定义只需要在参数后面加一个 ?

    const add = (x: number, y: number, z?: number): number => {
        return x + y + ( z ? z : 0 )
    }
    
    console.log(add(1 , 2));  // 3
    console.log(add(1 , 2, 3));  // 6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    可选参数可以是一个或者多个

    const add = (x: number, y?: number, z?: number): number => {
        return x + ( y ? y : 0 ) + ( z ? z : 0 )
    }
    
    console.log(add(1 , 2));  // 3
    
    • 1
    • 2
    • 3
    • 4
    • 5

    一旦出现可选参数后面只能跟可选参数

    const add = (x: number, y?: number, z: number): number => {  // error   必选参数不能位于可选参数后
        return x + ( y ? y : 0 ) + ( z ? z : 0 )
    }
    
    • 1
    • 2
    • 3

    2. 默认参数

    默认参数只需要给参数赋一个初值

    const add = (x, y = 20) => {
        console.log(x + y);
    }
    
    add(10);  // 30
    add(10, 70);  // 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    当为参数指定了默认参数时,TS会识别默认值推断此参数的类型。在调用函数时,如果实参类型和默认参数类型不一致则会报错

    const add = (x, y = 20) => {
        console.log(x + y);
    }
    
    add(10);  // 30
    add(10, '70');  // error  类型“string”的参数不能赋给类型“number”的参数。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    当然也可以显式的给默认参数设置类型

    const add = (x: number, y: number = 20): void => {
        console.log(x + y);
    }
    
    add(10);  // 30
    add(10, 60);  // 70
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3. 剩余参数

    剩余参数会被当做个数不限的可选参数。 可以一个都没有,同样也可以有任意个。 编译器会创建参数数组,名字是在 省略号... 后面给定的名字,可以在函数体内使用这个数组。

    const add = (...args: number[] ) => {
        const res = args.reduce((pre, cur) => {
           return pre + cur
        })
        console.log(res);
    }
    
    add(1, 2, 3); // 6
    add(10, 20, 30, 50, 90);  // 200
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    函数重载

    函数名相同, 而形参不同的多个函数

    所谓函数重载就是同一个函数,根据传递的参数不同,会有不同的表现形式。

    在JS中, 由于弱类型的特点和形参与实参可以不匹配, 是没有函数重载这一说的 但在TS中, 与其它面向对象的语言就存在此语法

    // 需求: 定义一个add函数,它可以接收2个string类型的参数进行拼接,也可以接收2个number类型的参数进行相加 
    
    // 重载函数声明
    function add (x: string, y: string): string;
    function add (x: number, y: number): number;
    
    // 定义函数实现
    function add(x: string | number, y: string | number): string | number | undefined {
        if(typeof x === 'string' && typeof y === 'string') return x + y;
        else if(typeof x === 'number' && typeof y === 'number') return x + y;
    }
    
    console.log(add(1, 2));  // 3
    console.log(add('温情', 'key'));  // 温情key
    
    
    console.log(add(1, 'key'));  // 报错信息如下
    // 第 1 个重载(共 2 个),“(x: string, y: string): string”,出现以下错误。
    // 类型“number”的参数不能赋给类型“string”的参数。
    // 第 2 个重载(共 2 个),“(x: number, y: number): number”,出现以下错误。
    // 类型“string”的参数不能赋给类型“number”的参数。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意: 函数重载只能用 function 来定义,不能使用interface type来定义。

  • 相关阅读:
    软件测试/测试开发丨接口测试学习笔记,TcpDump与WireShark
    2022.8.8-8.14 AI行业周刊(第110期):值钱比赚钱更重要
    图形学 - 纹理的应用
    hive之full outer join(全连接)使用方法
    在九天服务器平台上使用自己上传的数据集文件
    数据库-数据定义和操纵-DDL语言的使用
    Android 和Java 的关系
    【笔试题】位运算
    读写分离--mysql主从复制配置
    Embind方便的实现js与C++的交互
  • 原文地址:https://blog.csdn.net/qq_48960335/article/details/125609863