• TypeScript-02基础知识之函数


    目录

    1、函数类型表达式

    2、调用签名

     3、构造签名

    4、泛型函数

            函数泛型的限制条件

            约束条件中常见的错误使用

    5、指定类型参数

    6、优秀函数编写的准则

    7、函数参数的应用

    8、函数的重载

    9、其他类型

    10、参数扩展运算符 与 参数解构


     

    1、函数类型表达式

    1. // (a: string) => void 意味着 "有一个参数为string的函数,没有返回值"。
    2. function greeter(fn: (a: string) => void) {
    3. fn("Hello, World");
    4. }
    5. function printToConsole(s: string) {
    6. console.log(s);
    7. }
    8. greeter(printToConsole);
    9. // 使用类型别名定义函数
    10. let fun = (a:String) => void;
    11. function greeter(fn: fun){
    12. // ...
    13. }

    2、调用签名

            在js中函数除了可以用来调用,函数还可以拥有属性。只是在函数类型表达式的语法不允许声明属性。 如果我们想用属性来描述可调用的东西,我们可以在一个对象类型中写一个调用签名。<与函数类型表达式相比,语法略有不同:在参数列表和返回类型之间使用 : 而不是 =>>

    1. type newDataType = {
    2. x: String,
    3. (a: String): Boolean //与函数类型表达式相比,语法略有不同:在参数列表和返回类型之间使用 : 而不是 =>
    4. }
    5. function handleFunction(fn: newDataType){
    6. console.log(fn.x + "return " + fn("hhh"))
    7. }
    8. function fn(str){
    9. return false
    10. }
    11. fn.x = "llllll"
    12. handleFunction(fn)

     3、构造签名

            在js中函数可以通过new关键词来调用,这在js和ts中称之为构造函数;因为通过new出来的一般都是一个新对象。即可以通过在调用签名前面添加new关键字来写一个构造签名

    1. class dataType{
    2. s: Number,
    3. constructor(s: Number){
    4. this.s = s;
    5. }
    6. }
    7. type newDataType = {
    8. new (s:Number): dataType
    9. }
    10. function handleType(dType: newDataType){
    11. return new dType(222);
    12. }
    13. console.log(handleType(dataType).s) // 打印出 222

    4、泛型函数

            在写一个函数时,输入的类型与输出的类型有关,或者两个输入的类型以某种方式相关,这是常见的。  在TypeScript中,当我们想描述两个值之间的对应关系时,会使用泛型

    1. // 通过给这个函数添加一个类型参数 Type ,并在两个地方使用它,即已经在函数的输入(数组)和输出(返回值)之间建立了一个联系。现在调用它时,一个更具体的类型就出来了
    2. function firstArr<Type>(arr: Type<>){
    3. return arr[0];
    4. }
    5. // 调用函数
    6. // s 的类型这时候就为Number
    7. const s = firstArr([1,2,3,4])
    8. // s1 的类型这时候就为String
    9. const s1 = firstArr(['a','b','c','d'])
    10. // s2 的类型这时候就为undefined
    11. const s2 = firstArr([])

            函数泛型的限制条件

    1. // Type 约束为 { length: number } ,所以我们被允许访问 a 和 b 参数的 .length 属性。
    2. // 如果没有类型约束,我们就不能访问一些属性(会报错),因为这些值可能是一些没有长度属性的其他类型。
    3. function longest<Type extends { length: number }>(a: Type, b: Type) {
    4. if (a.length >= b.length) {
    5. return a;
    6. } else {
    7. return b;
    8. }
    9. }
    10. // longerArray 的类型是 'number[]'
    11. const longerArray = longest([1, 2], [1, 2, 3]);
    12. // longerString 是 'alice'|'bob' 的类型。
    13. const longerString = longest("alice", "bob");
    14. // 错误! 数字没有'长度'属性
    15. const notOK = longest(10, 100);
    16. // longerArray 和 longerString 的类型是根据参数推断出来的。
    17. // 泛型就是把两个或多个具有相同类型的值联系起来。

            约束条件中常见的错误使用

    1. function handelData<Type extends {length: Number}>(data: Type,flag: Number): Type{
    2. if(data.length > flag){
    3. return data
    4. } else{
    5. return {length: flag} // 错误,因为Type的类型不一定是个对象,即Type不一定要与其 限制值一致
    6. }
    7. }
    8. // 'arr' 获得值: { length: 6 }
    9. const arr = handelData([1, 2, 3], 6);
    10. // 错误,因为数组有一个'切片'方法,但对象没有
    11. console.log(arr.slice(0));

    5、指定类型参数

    1. // 指定函数返回的类型为Type[],但是在某些时候调用这个函数会出现错误
    2. function concatArray<Type>(a: Type[],b: Type[]): Type[]{
    3. return a.concat(b)
    4. }
    5. concatArray([1,2,3,4,5],["hello"]) // 报错,正常返回的类型推断的应该是 Number[],现在返回的是一个混合数组,所以函数应该这样更改
    6. concatArray<Number | String>([1,2,3,4,5],["hello"]) // 手动指定类型

    6、优秀函数编写的准则

    1. // 1、使用类型参数本身,而不是对其进行约束
    2. function firstElement1<Type>(arr: Type[]) {
    3. return arr[0];
    4. }
    5. function firstElement2<Type extends any[]>(arr: Type) {
    6. return arr[0];
    7. }
    8. // a: number (推荐)
    9. const a = firstElement1([1, 2, 3]);
    10. // b: any (不推荐)
    11. const b = firstElement2([1, 2, 3]);
    12. // 2、总是尽可能少地使用类型参数
    13. function filter1<Type>(arr: Type[], func: (arg: Type) => boolean): Type[] {
    14. return arr.filter(func);
    15. }
    16. // Func extends 就没有要的必要
    17. function filter2<Type, Func extends (arg: Type) => boolean>(
    18. arr: Type[],
    19. func: Func
    20. ): Type[] {
    21. return arr.filter(func);
    22. }
    23. // 3、如果一个类型的参数只出现在一个地方,请重新考虑你是否真的需要它

    7、函数参数的应用

    可选参数:在TypeScript的函数中,传递参数时,在参数的后面加上 ? 就表示该参数是可选参数。注意:虽然可选参数会被指定为某种类型,但该参数实际上将具有 某种类型 | undefined 类型,因为在 JavaScript中未指定的参数会得到 undefined 的值。

            当为回调函数写参数是,一定要避免使用可选参数,除非你不打算使用这个参数。

    8、函数的重载

            在TypeScript中,我们可以通过编写重载签名来指定一个可以以不同方式调用的函数。要做到这一点, 要写一些数量的函数签名(通常是两个或更多)+ 函数的主体

    1. function makeDate(timestamp: number): Date; // 传递时间戳的重载函数签名
    2. function makeDate(m: number, d: number, y: number): Date;// 传递三个参数(月、日、年)的重载函数签名
    3. // 函数主体
    4. function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
    5. if (d !== undefined && y !== undefined) {
    6. return new Date(y, mOrTimestamp, d);
    7. } else {
    8. return new Date(mOrTimestamp);
    9. }
    10. }
    11. const d1 = makeDate(12345678); // 传递时间戳
    12. const d2 = makeDate(5, 5, 5); // 传递三个参数
    13. const d3 = makeDate(1, 3); // 错误,因为没有对应的重载函数签名与之对应

    9、其他类型

            void 表示没有返回值的函数的返回值。当一个函数没有任何返回语句,或者没有从这些返回语句中返回任何明确的值时,它都是推断出来的类型。

            unknown 类型代表任何值。这与 any 类型类似,但更安全,因为对未知 unknown 值做任何事情都是不合法的。 这在描述函数类型时很有用,因为你可以描述接受任何值的函数,而不需要在函数体中有 any 值。 反之,你可以描述一个返回未知类型的值的函数。

            never 类型表示永远不会被观察到的值。在一个返回类型中,这意味着函数抛出一个异常或终止程序的执行。 never 也出现在TypeScript确定一个 union 中没有任何东西的时候。 

    10、参数扩展运算符 与 参数解构

    1. function multiply(n: number, ...m: number[]) {
    2. return m.map((x) => n * x);
    3. }
    4. // 'a' 获得的值 [10, 20, 30, 40]
    5. const a = multiply(10, 1, 2, 3, 4);
    6. // 展开数组
    7. const arr1 = [1, 2, 3];
    8. const arr2 = [4, 5, 6];
    9. arr1.push(...arr2);
    10. // ==============================参数解构==============================
    11. // 函数参数简写版
    12. function sum({ a, b, c }) {
    13. console.log(a + b + c);
    14. }
    15. // 详细版
    16. function sum({ a, b, c }: ABC) {
    17. console.log(a + b + c);
    18. }
    19. sum({ a: 10, b: 3, c: 9 })
  • 相关阅读:
    Jenkins + Gitee 实现代码自动化构建 (超级详细)
    MongoDB之MongoDBConnectorBI安装与使用
    【Helm三部曲】 Helm 简介及安装
    C专家编程学习记录
    Jenkins - macOS 上安装
    Android学习之路(21) 进程间通信-AIDL与Servce基本使用
    牛客网刷题篇
    地址栏 Url 乱码问题
    脱离CRUD苦海 !性能优化全栈小册来了!
    12.4泛型 map set
  • 原文地址:https://blog.csdn.net/m0_51992766/article/details/127602939