typeScript中的函數類型

函數的標註

一個函數的標註包含css

  • 參數
  • 返回值
function fn(a: string): string {};
let fn: (a: string) => string = function(a) {};

type callback = (a: string): string;
interface ICallBack {
  (a: string): string;
}

let fn: callback = function(a) {};
let fn: ICallBack = function(a) {};
複製代碼

可選參數和默認參數

可選參數

經過參數名後面添加 ? 來標註該參數是可選的typescript

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

}
// 設置
div && css( div, 'width', '100px' );
// 獲取
div && css( div, 'width' );
複製代碼

默認參數

咱們還能夠給參數設置默認值數組

  • 有默認值的參數也是可選的
  • 設置了默認值的參數能夠根據值自動推導類型
function sort(items: Array<number>, order = 'desc') {}
sort([1,2,3]);

// 也能夠經過聯合類型來限制取值
function sort(items: Array<number>, order:'desc'|'asc' = 'desc') {}
// ok
sort([1,2,3]);
// ok
sort([1,2,3], 'asc');
// error
sort([1,2,3], 'abc');
複製代碼

剩餘參數

剩餘參數是一個數組,因此標註的時候必定要注意ide

interface IObj {
    [key:string]: any;
}
function merge(target: IObj, ...others: Array<IObj>) {
    return others.reduce( (prev, currnet) => {
        prev = Object.assign(prev, currnet);
        return prev;
    }, target );
}
let newObj = merge({x: 1}, {y: 2}, {z: 3});
複製代碼

函數中的 this

不管是 JavaScript 仍是 TypeScript ,函數中的 this 都是咱們須要關心的,那函數中 this 的類型該如何進行標註呢?函數

  • 普通函數
  • 箭頭函數

普通函數

對於普通函數而言,this 是會隨着調用環境的變化而變化的,因此默認狀況下,普通函數中的 this 被標註爲 any, 但咱們能夠在函數的第一個參數位(它不佔據實際參數位置)上顯式的標註 this 的類型ui

interface T {
    a: number;
    fn: (x: number) => void;
}

let obj1:T = {
    a: 1,
    fn(x: number) {
        //any類型
        console.log(this);
    }
}

let obj2:T = {
    a: 1,
    fn(this: T, x: number) {
        //經過第一個參數位標註 this 的類型,它對實際參數不會有影響
        console.log(this); // obj2
    }
}
obj2.fn(1);
複製代碼

箭頭函數

箭頭函數的 this 不能像普通函數那樣進行標註,它的 this 標註類型取決於它所在的做用域 this 的標註類型this

interface T {
    a: number;
    fn: (x: number) => void;
}

let obj2: T = {
    a: 2,
    fn(this: T) {
        return () => {
            // T
            console.log(this);
        }
    }
}
複製代碼

函數重載

有的時候,同一個函數會接收不一樣類型的參數返回不一樣類型的返回值,咱們能夠使用函數重載來實現,經過下面的例子來體會一下函數重載spa

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,這裏是有問題的,雖然經過聯合類型可以處理同時接收不一樣類型的參數,可是多個參數之間是一種組合的模式,咱們須要的應該是一種對應的關係
  showOrHide( div, 'display', 1 );
}
複製代碼

咱們來看一下函數重載code

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 );
  // 經過函數重載能夠設置不一樣的參數對應關係
  showOrHide( div, 'display', 1 );
}
複製代碼
  • 重載函數類型只須要定義結構,不須要實體,相似接口
interface PlainObject {
    [key: string]: string|number;
}

function css(ele: HTMLElement, attr: PlainObject);
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 in attr) {
            ele.style[attr] = attr[key];
        }
    }
}

let div = document.querySelector('div');
if (div) {
    css(div, 'width', '100px');
    css(div, {
        width: '100px'
    });

    // error,若是不使用重載,這裏就會有問題了
    css(div, 'width');
}
複製代碼
相關文章
相關標籤/搜索