TypeScript學習(基礎篇一)

數據類型

js的數據類型有七種:Boolean,Number,Object所灸,Array,null炫七,undefined爬立,Symbol

類型

這里就說幾個比較特別需要注意的點

空值(Void)

在js中沒有空值的概念,在ts中万哪,可以用void表示沒有任何返回值的函數

function alertName():void {
    alert("my name is lhy");
}

然而聲明一個void類型的變量沒有什么用侠驯,因為你只能將它賦值為null和undefined。

let undisable: void = undefined;

任意類型(any)

如果是一個普通的類型奕巍,在賦值過程中改變類型是不允許的吟策,但是任意類型是可以的

let anything: any = {} | null |'' | 0

聲明了一個變量為任意值之后,對它的任何操作和返回的內容的類型都是任意值的止。

并且一個變量如果沒有聲明任何一個類型檩坚,那么它默認就是任意類型。(但是我瞅著好像在我代碼里面并不是這樣)

聯合類型

聯合類型使用 | 來分割每個類型。

let test: string | number

訪問聯合屬性的方法:我們必須只能訪問此聯合類型里公用的屬性和方法

錯誤:

function getLength(something: string | number): number {
    return something.length;
}

number沒有l(wèi)ength這個屬性

正確:

function getString(something: string | number): string {
    return something.toString();
}

所以匾委,聯合類型在被賦值的時候拖叙,會根據類型推論的規(guī)則推斷出一個類型。

對象的類型-interface(接口)

TS中interface是一個很靈活的概念剩檀,除了可以用于對類的一部分行為進行抽象以外憋沿,也常用于對“對象的形狀”進行描述

規(guī)范:接口一般首字母大寫,有的編程語言中會建議接口的名稱加上I前綴

interface IPerson {
    name: string;
    age: number;
}

let tom: IPerson = {
    name: 'Tom',
    age: 25
};

這種的接口沪猴,則要求賦值的時候,變量的形狀必須和接口的形狀保持一直采章,如果想要擁有任意的未添加定義的屬性运嗜,可以??

可選屬性/任意屬性

interface Person {
    name: string;
    age?: number;
    [propName: string]: any;
}

這個樣子變量就可以擁有任意的未添加的定義屬性

只讀屬性

有的時候我們希望對象中的一些字段只能在創(chuàng)建的時候被賦值,那么可以用readonly只讀屬性悯舟。

interface IPerson {
    readonly id: number;
    test: string;
}
let person: IPerson {
        id: 123;
    test: 'xxx'
}
// 這個時候試圖去改變id的值則會報錯
person.id = 90; 
// 報錯5W狻!抵怎!

只讀的約束存在于第一次給對象賦值的時候奋救,而不是第一次給只讀屬性賦值的時候

數組的類型

最簡單的使用方法就是類型+方括號來表示數組:

let test:number[] = [1, 2, 3, 4]
//  這個數組里面只能是數字

數組泛型( 常用)

let test: Array<number> = [1, 2, 4];

用接口來表示數組

interface NumberArray {
    [index: number]: number
}
let fibonacci: NumberArray = [1, 1, 2, 3, 5];

函數的類型

函數是js里面最重要的成員之一!反惕!

一個函數有輸入和輸出尝艘,要在ts中對其進行約束,則需要把輸入和輸出都考慮到姿染,最簡單的例子:

let mySum = function (x: number, y: number): number {
    return x + y;
};
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
    return x + y;
};

利用接口定義函數的形狀

interface SearchFunc {
    (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
    return source.search(subString) !== -1;
}

此外背亥,對于函數而言,可選參數后面不允許再出現必須參數了

錯誤:

function buildName(firstName?: string, lastName: string) {
    if (firstName) {
        return firstName + ' ' + lastName;
    } else {
        return lastName;
    }
}
// errorP汀=坪骸!C銎摹盾戴!

但是如果我們給參數設置了默認值,那么就不受這個規(guī)則的限制了1唷尖啡!

剩余參數

ES6中,可以使用...reset 的方式獲取函數中的剩余參數中鼠。舉例如下:

function push(array, ...items) {
    items.forEach(function(item) {
        array.push(item);
    });
}

let a = [];
push(a, 1, 2, 3);

函數重載

重載允許一個函數接受不同數量或類型的參數可婶,作出不同的處理。

比如我們需要實現一個reverse函數援雇,輸入數字 123 的時候矛渴,輸出反轉的數字 321,輸入字符串 'hello' 的時候,輸出反轉的字符串 'olleh'具温。

利用聯合類型蚕涤,我們可以這么實現:

function reverse(x: number | y: number): number | string {
if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}

但是這樣寫的話,代碼的可讀性并不是很高铣猩,就是輸入數字的時候揖铜,輸出也應該是數字,輸入字符串的時候达皿,輸出也應該是字符串天吓,這個時候我們可以用重載去定義reverse函數

function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}

在代碼中我們可以看見,我們重復定義了多次函數 reverse峦椰,前幾次都是函數定義龄寞,最后一次是函數實現。

類型斷言(便捷汤功,不必使用typeof 判斷)

之前有說過物邑,當 TypeScript 不確定一個聯合類型的變量到底是哪個類型的時候,我們只能訪問此聯合類型的所有類型里共有的屬性或方法滔金,而有時候色解,我們確實還是需要在還不確定類型的時候就訪問其中一個類型的屬性或方法,比如

function getLength(something: string | number): number {
    if (something.length) {
        return something.length;
    } else {
        return something.toString().length;
    }
}

此時會報錯2鸵稹?蒲帧!

/ index.ts(2,19): error TS2339: Property 'length' does not exist on type 'string | number'.

// Property 'length' does not exist on type 'number'.

// index.ts(3,26): error TS2339: Property 'length' does not exist on type 'string | number'.

// Property 'length' does not exist on type 'number'.

這個時候我們可以非常方便的使用類型斷言

function getLength(something: string | number): number {
// 在需要斷言的變量前面增加類型V硬 O羲 !3濉票唆! 避免寫 typeof something === 'string' && something.length 這么復雜了!R倥恰走趋!
    if ((<string>something).length) {
        return (<string>something).length;
    } else {
        return something.toString().length;
    }
}

聲明文件

通常我們會把聲明語句放在一個單獨的文件里,這就是聲明文件噪伊,例如創(chuàng)建一個聲明文件jQuery.d.ts,里面的聲明語句如下:

declare var JQuery:(selector: string) => any;

一般來說簿煌,ts會解析項目中所有的.ts文件,當然也包含以.d.ts結尾的文件鉴吹,所以當我們將 jQuery.d.ts 放到項目中時姨伟,其他所有 *.ts 文件就都可以獲得 jQuery 的類型定義了。

/path/to/project
├── src
|  ├── index.ts
|  └── jQuery.d.ts
└── tsconfig.json

加入仍然無法解析豆励,那么可以檢查下tsconfig.json里面的file, include和exclude的配置夺荒。確保其包含了jQuery.d.ts文件瞒渠。

第三方聲明(經常用到)

當然,jQuery 的聲明文件不需要我們定義了技扼,社區(qū)已經幫我們定義好了:jQuery in DefinitelyTyped伍玖。

我們可以直接下載下來使用,但是更推薦的是使用 @types 統(tǒng)一管理第三方庫的聲明文件剿吻。

@types 的使用方式很簡單窍箍,直接用 npm 安裝對應的聲明模塊即可,以 jQuery 舉例:

npm install @types/jquery --save-dev

可以在這個頁面搜索你需要的聲明文件丽旅。在項目里面椰棘,基本上都會用到第三方聲明文件。

但是當一個第三方庫沒有提供我們想要的聲明文件的時候榄笙,我們需要去手動書寫聲明文件晰搀,這樣就得了解聲明語句了。??

手寫聲明文件

理論上來說办斑,會在項目里面建立一個types文件夾,然后將我們所有的聲明文件放在該目錄下杆逗,然后這種方式需要配置tsconfig.json中的paths和bathUrl字段乡翅。

tsconfig.json的配置:

{
    "compilerOptions": {
        "module": "commonjs",
        "baseUrl": "./",
        "paths": {
            "*": ["types/*"]
        }
    }
}

內置對象

JS提供的標準對象有:Boolean, error, Date, RegExp等

我們可以在ts中將變量定義為這些類型:

let b: Boolean = new Boolean(1);

let e: Error = new Error('Error occurred');

let d: Date = new Date();

let r: RegExp = /[a-z]/;

DOM和BOM的內置對象

DOM 和 BOM提供的內置對象有:

Document, HTMLElement, Event, NodeList等。

TS中會經常用到這些類型:

let body: HTMLElement = document.body;
let allDiv: NodeList = document.querySelectorAll('div');
document.addEventListener('click', function(e: MouseEvent){
 // do something
})

這些類型的定義文件都在ts核心庫定義文件

TS核心庫定義文件

TS核心庫中的定義文件中定義了所有瀏覽器環(huán)境需要用到的類型罪郊,并且是預置在TS中的蠕蚜。

當你在使用一些常用方法的時候,TS實際上已經幫你做了很多類型判斷的工作悔橄。比如:

Math.pow(10, '2');

// index.ts(1,14): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
就是這個函數的兩個參數必須都是Number類型

想要用TS寫node.js

Node.js不是內置對象的一部分靶累,如果想要用Node.js寫TS,則需要引入第三方聲明文件:

npm install @types/node --save

參考:https://ts.xcatliu.com/engineering/lint

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末癣疟,一起剝皮案震驚了整個濱河市挣柬,隨后出現的幾起案子,更是在濱河造成了極大的恐慌睛挚,老刑警劉巖邪蛔,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異扎狱,居然都是意外死亡侧到,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門淤击,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匠抗,“玉大人,你說我怎么就攤上這事污抬」常” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長著蛙。 經常有香客問我删铃,道長,這世上最難降的妖魔是什么踏堡? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任猎唁,我火速辦了婚禮,結果婚禮上顷蟆,老公的妹妹穿的比我還像新娘诫隅。我一直安慰自己,他們只是感情好帐偎,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布逐纬。 她就那樣靜靜地躺著,像睡著了一般削樊。 火紅的嫁衣襯著肌膚如雪豁生。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天漫贞,我揣著相機與錄音甸箱,去河邊找鬼。 笑死迅脐,一個胖子當著我的面吹牛芍殖,可吹牛的內容都是我干的。 我是一名探鬼主播谴蔑,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼豌骏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了隐锭?” 一聲冷哼從身側響起窃躲,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎成榜,沒想到半個月后框舔,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡赎婚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年刘绣,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挣输。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡纬凤,死狀恐怖,靈堂內的尸體忽然破棺而出撩嚼,到底是詐尸還是另有隱情停士,我是刑警寧澤挖帘,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站恋技,受9級特大地震影響拇舀,放射性物質發(fā)生泄漏。R本人自食惡果不足惜蜻底,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一骄崩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薄辅,春花似錦要拂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至窿春,卻和暖如春拉一,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背旧乞。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工舅踪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人良蛮。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像悍赢,于是被迫代替她去往敵國和親决瞳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348