A detailed solution of the function of TS

Learning goals

  • Understand function type annotations in TypeScript
  • Function optional arguments, default arguments, remaining arguments
  • This in the function
  • Function overloading

1. Annotation of functions

The annotation of a function contains

  • parameter
  • The return value
// Two ways to create and declare functions
// 1
function fn1(a: string) :string {
    return ' '
}

// 2
let fn2: (a: string) = > string = function (a) {
    return ' '
}

// type
type callback = (a: string) = > string;
// interface
interface ICallback {
    (a: string) :string;
}

let fn3: callback = function (a) { return ' ' }
let fn4: ICallback = function (a) { return ' ' }
Copy the code

2. Optional parameters, default parameters, remaining parameters

Optional parameters

Add? After the parameter name. To note that this parameter is optional

let div = document.querySelector('div')
function css(el: HTMLElement, attr: string, val? :any) {
    / /... Function implementation
}

/ / set
div && css(div, 'width'.'100px')

/ / to get
div && css(div, 'width')
Copy the code

The default parameters

We can also set default values for the parameters

  • Parameters with default values are also optional
  • Parameters with default values canAutomatically derive types from values
function sort(items: Array<number>, order = 'desc') {}// set a default order='desc'
sort([1.2.3.4])
sort([1.2.3.4].'asc')

// The value can also be limited by the union type
function sort(items: Array<number>, order:'desc'|'asc' = 'desc') {}
// ok
sort([1.2.3]);
// ok
sort([1.2.3].'asc');
/ / the error an error
sort([1.2.3].'abc');
Copy the code

The remaining parameters

The remaining parameters are an array, so be careful when annotating

interface IObj {
    [key: string] :any
}

// Object merge function
function merge(target: IObj, ... others:Array<IObj>) {
    return Object.assign(target, ... others); }let newobj = merge({ x: 1 }, { y: 2 }, { z: 3 })
Copy the code

3. This in function

Common function

For normal functions, this changes with the calling environment, so by default, this is labeled any, but we can explicitly label the type of this on the first argument bit of the function (which does not take up the actual argument position)

Arrow function

The arrow function’s this cannot be annotated like a normal function; its this annotation type depends on the annotation type of this in its scope

4. Function overload

Sometimes, the same function may take different types of arguments and return different types of values. We can use function overloading to do this

Usage scenario: Only one set of rules, easy to error

function showOrHide(ele: HTMLElement, attr: string, value:
    'block' | 'none' | number) {
    //
}
let div = document.querySelector('div');
if (div) {
    showOrHide(div, 'display'.'none');
    showOrHide(div, 'opacity'.1);
    // Error, this is a problem, but eslink does not report an error, although through the union type can handle the simultaneous receipt of different types of parameters, but multiple parameters are a combination of patterns, we need a corresponding relationship should be
    showOrHide(div, 'display'.1);
}
Copy the code

Let’s look at function overloading

function showOrHide(ele: HTMLElement, attr: 'display', value: 'block' | 'none');
function showOrHide(ele: HTMLElement, attr: 'opacity', value: number);
function showOrHide(ele: HTMLElement, attr: string, value: any) {
    ele.style[attr] = value;
}
let div = document.querySelector('div');
if (div) {
    showOrHide(div, 'display'.'none');
    showOrHide(div, 'opacity'.1);
    // Error can set different parameter mappings through function overloading
    showOrHide(div, 'display'.1);
}
Copy the code

Case 2: Overloaded function types only need to define structures, not entities, like interfaces

// Encapsulate CSS method Settings

interface PlainObject {
    [key: string] :string | number;
}
function css(ele: HTMLElement, attr: PlainObject); // The second parameter is the object
function css(ele: HTMLElement, attr: string, value: string | number);
function css(ele: HTMLElement, attr: any, value? :any) {
    if (typeof attr === 'string' && value) {
        ele.style[attr] = value;
    }
    if (typeof attr === 'object') {
        for (let key inattr) { ele.style[attr] = attr[key]; }}}let div = document.querySelector('div');
if (div) {
    css(div, 'width'.'100px');
    css(div, {
        width: '100px'
    });
    // error, if you don't use overloading, there will be a problem here
    css(div, 'width');
}
Copy the code