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 can
Automatically 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