Function extension in TS

Posted by Gibb Boy on Sun, 03 May 2020 13:37:36 +0200

Function extension in TS

Full function type

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

  //Complete function defined in ts
  let add: (x: number, y: number) => number
    = function(x: numer, y: number):number {
      return x + y;
    }
  //The parameters in the function do not need to be consistent with the parameters in the type declaration, as long as the parameter types are consistent
  function (baseValue: number, increment: number) {
    return x + y;
  }
  //Of course, you can also use the type inference function in ts, without declaring parameter types in the function. ts will check automatically according to the context, such as:
  let add: (x: number, y: number) => number
    = function(x,y){return x + y;}

  //This is the advantage of defining functions in ts, which keeps you aware of your original ideas and keeps you from deviating from the original orbit,
  //Always restrain you from making mistakes, ha ha

Optional and default parameters

  //In js, each parameter is optional. It can be passed but not passed. If it is not passed, its value is undefined. But in ts, it is not so comfortable. If you define the number of function parameters, you must pass as many as you want. Otherwise, an error will be reported
  function buildName(firstName: string, lastName: stirng){
    return firstName + " " + lastName;
  }
  let result1 = buildName("Bob"); //error
  let result2 = buildName("Bob", "Yu"); //right
  let result3 = bulidName("Bob", "Yu" , "Sr."); //error

  //Representation of optional parameters in ts
  //In addition, it should be noted that the optional parameters must follow the required parameters, and this order cannot be disordered
  function buildName(firstName: string, lastName?: string){
    if(lastName){
      return firstName + " " + lastName;
    }else{
      return firstName;
    }
  }

  //The representation of default parameters in ts
  //In ts, if the user does not pass this parameter or the passed value is undefined, you can set this parameter as the default parameter, i.e. the parameter of the default initialization value, if you want.
  function buildName (firstName: string, lastName: string = "Smith"){
    return firstName + " " + lastName;
  }

Remaining parameters

Necessary parameters, default parameters and optional parameters have one thing in common: they represent a certain parameter. When you want to operate on multiple parameters at the same time, or you don't know how many parameters will be passed in. In js, you can use arguments object to access, of course, in ts. In ts, we collect all the parameters into an array.

  function buildName(firstName: stirng, ...restOfName: string[]){
    return firstName + " " + restOfName.join(" ");
  }

this and arrow functions

this is very good, but generally good things are not allowed, ha ha

  //js
  let deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    createCardPicker: function(){
      return function(){
        let pickedCard = Math.floor(Math.random() * 52);
        let pickedSuit = Math.floor(pickedCard / 13);
        return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
      }
    }
  };
  let cardPicker = deck.createCardPicker();
  let pickedCard = cardPicker();
  console.log("card: " + pickedCard.card + " of " + pickedCard.suit);
  //If you try to run the above program, you will find that there is no pop-up dialog box, but an error is reported. Because this in the function returned by createCardPicker is set to window instead of deck object.
  //To solve this problem, we can bind the correct this when the function is returned. The arrow function can save this value when the function is created, rather than when it is called. this + Ts is a perfect match.

  //ts rewrites the above example
  interface Card {
    suit: string;
    card: number;
  }
  interface Deck {
    suits: string[];
    cards: number[];
    createCardPicker(this: Deck): () => Card;
  }
  let deck: Deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    card: Array(52),
    createCardPicker: function(this: Deck) {
      return () => {
        let pickedCard = Math.floor(Math.random() * 52);
        let pickedSuit = Math.floor(pickedCard / 13);
        return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
      }
    }
  }
  let cardPicker = deck.createCardPicker();
  let pickedCard = cardPicker();
  console.log("card: " + pickedCard.card + " of " + pickedCard.suit);

heavy load

There are no overloads in js, but it is gratifying that overloads can be used in ts

  let suits = ["hearts", "spades", "clubs", "diamonds"];
  function pickCard(x: {suit: string; card: number;}[]) : number;
  function pickCard(x: number) : {suit: string; card: number};
  function pickCard(x) : any {
    if(typeof x == "object"){
      let pickedCard = Math.floor(Math.random() * x.length);
      return pickedCard;
    }
    else if (typeof x == "number") {
      let pickedSuit = Math.floor(x / 13);
      return { suit: suits[pickedSuit], card: x % 13 };
    }
  }
  //object
  let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
  let pickedCard1 = myDeck[pickCard(myDeck)];
  alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);
  //number
  let pickedCard2 = pickCard(15);
  alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

  //Note: function pickCard(x): any is not part of the overload list, so there are only two overloads here: one is the receiving object, the other is the receiving number.
  //In order for the compiler to choose the right type of check, it is similar to the processing flow in javascript. First look up the overload list, try to use the first overload definition, and use this if it matches. Therefore, when defining overload, we must put the most accurate definition at the top.

Topics: Javascript