爲vue3學點typescript, 基礎類型和入門高級類型

導航

第一課, 體驗typescriptjavascript

第二課, 基礎類型和入門高級類型vue

第三課, 泛型java

第四課, 解讀高級類型git

第五課, 什麼是命名空間(namespace)?github

很重要

這一節很重要, 能夠說是ts的最核心部分, 這一節學完其實就能夠開始用ts寫代碼了, 想一想typescript中的type, 再看看標題中的"類型"2字, 因此請你們務必認真.typescript

什麼是入門高級類型

由於高級類型的內容比較多, 可是有些基礎類型的知識點還必需要用到高級類型的知識講解才連貫, 因此本節課把最經常使用的高級類型提早講解一下, 好比接口/聯合類型/交叉類型.segmentfault

基礎類型

ts中基礎類型有以下幾種:boolean / number / string / object / 數組 / 元組 / 枚舉 / any / undefined / null / void / never, 下面咱們一一舉例學習:數組

字面量

介紹類型前,有一個前置知識點就是字面量, 字面量的意思就是直接聲明, 而非new關鍵詞實例化出來的數據:dom

// 字面量
const n:number = 123;
const s:string = '456';
const o:object = {a:1,b:'2'};

// 非字面量
const n:Number = new Number(123);
const s:String = new String('456');
const o:Object = new Object({a:1,b:'2'});

經過上面的例子, 你們應該看明白爲何ts中有些類型的開頭字母是小寫的了吧. 這是由於ts中用小寫字母開頭的類型表明字面量, 大寫的是用來表示經過new實例化的數據.函數

boolean

布爾類型, 取值只有true / false

const IS_MOBILE:boolean = true;
const IS_TABLE:boolean = false;

number

數字類型, 整數/小數都包括, 同時支持2/8/10/16進制字面量.

let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744;

string

字符串類型

let s1:string = 'hello world!';
let s2:string = 'hello ${name}`;

數組

數組有2種表示方式:

第1種, 經過在指定類型後面增長[], 表示該數組內的元素都是該指定類型:

let numbers:number[] = [1,2,3,4,5];
// number|string表明聯合類型, 下面的高級類型中會講
let numbers:(number|string)[] = [1,2,3,4,'5'];

第2種, 經過泛型表示, Array<元素類型>, 泛型會在後面課講解, 先作了解便可:

let numbers:Array<number> = [1,2,3,4,5];

元組(Tuple)

元組類型表示一個已知元素數量類型數組, 各元素的類型沒必要相同:

let list1:[number, string] = [1, '2', 3]; // 錯誤, 數量不對, 元組中只聲明有2個元素
let list2:[number, string] = [1, 2]; // 錯誤, 第二個元素類型不對, 應該是字符串'2'
let list3:[number, string] = ['1', 2]; // 錯誤, 2個元素的類型顛倒了
let list4:[number, string] = [1, '2']; // 正確

枚舉(enum)

枚舉是ts中有而js中沒有的類型, 編譯後會被轉化成對象, 默認元素的值從1開始, 以下面的Color.Red的值爲1, 以此類推Color.Green爲2, Color.Blue爲3:

enum Color {Red, Green, Blue}
// 等價
enum Color {Red=1, Green=2, Blue=3}

固然也能夠本身手動賦值:

enum Color {Red=1, Green=2, Blue=4}

而且咱們能夠反向經過值獲得他的鍵值:

enum Color {Red=1, Green=2, Blue=4}
Color[2] === 'Green' // true

看下編譯成js後的枚舉代碼, 你就明白爲何能夠反向獲得鍵值:

var Color;
(function (Color) {
    Color[Color["Red"] = 0] = "Red";
    Color[Color["Green"] = 1] = "Green";
    Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
// Color的值爲: {0: "Red", 1: "Green", 2: "Blue", Red: 0, Green: 1, Blue: 2}

any(任意類型)

any表明任意類型, 也就是說, 若是你不清楚變量是什麼類型, 就能夠用any進行標記, 好比引入一些比較老的js庫, 沒有聲明類型, 使用的時候就能夠標記爲any類型, 這樣ts就不會提示錯誤了. 固然不能全部的地方都用any, 那樣ts就沒有使用的意義了.

let obj:any = {};
// ts本身推導不出forEach中給obj增長了'a'和'b'字段.
['a', 'b'].forEach(letter=>{
    obj[letter] = letter;
});

// 可是由於標記了any, 因此ts認爲a可能存在
obj.a = 123

void

void的意義和any相反, 表示不是任何類型, 通常出如今函數中, 用來標記函數沒有返回值:

function abc(n:number):void{
    console.log(n);
}

void類型對應2個值, 一個是undefined,一個null:

const n1:void = undefined;
const n2:void = null;

null 和 undefined

默認狀況下null和undefined是全部類型的子類型, 好比:

const n1:null = 123;
const n2:undefined = '123';

注意: 這是由於默認狀況下的編譯選項strictNullChecks爲false, 可是爲了不一些奇怪的問題出現, 我仍是建議你們設置爲true(編譯選項設置的內容, 會在後面的課程講解), 請用精準的類型去標註.

若是一個變量的值確實須要是null或者undefined, 能夠像下面這麼用, ts會自動根據if/else推導出正確類型:

// 這是"聯合類型", 在"高級類型"中會有詳細介紹, 表示n多是undefined也多是number
let num: undefined|number;

if(Math.random()>0.5) num = 1;

if(undefined !== num) {
    num++;
}

never

never表示不可達, 用文字還真很差描述, 主要使用在throw的狀況下:

function error():never{
    throw '錯了!';
}

object

object表示非原始類型, 也就是除number/ ss/ boolean/ symbol/ null/ undefined以外的類型:

let o1:object = [];
let o2:object = {a:1,b:2};

可是, 咱們實際上基本不用object類型的, 由於他標註的很是不具體, 通常都用接口來標註更具體的對象類型, 請繼續看下面的接口的內容.

高級類型入門

經過基礎類型組合而來的, 咱們能夠叫他高級類型. 包含: 交叉類型 / 聯合類型 / 接口等等, 固然不止他們3個, 爲了避免讓本節課太長形成讀者疲勞, 本節只先講這3個, 不過不要着急, 下節課會完結高級類型.

接口(interface)

一種定義複雜類型的格式, 好比咱們用對象格式存儲一篇文章, 那麼就能夠用接口定義文章的類型:

interface Article {
    title: stirng;
    count: number;
    content:string;
    fromSite: string;
}

const article: Article = {
    title: '爲vue3學點typescript(2), 類型',
    count: 9999,
    content: 'xxx...',
    fromSite: 'baidu.com'
}

在這種狀況下,當咱們給article賦值的時候, 若是任何一個字段沒有被賦值或者字段對應的數據類型不對, ts都會提示錯誤, 這樣就保證了咱們寫代碼不會出現上述的小錯誤.

非必填(?)

仍是上面的例子, fromSite的意思是文章來自那個網站,若是文章都是原創的, 該字段就不會有值, 可是若是咱們不傳又會提示錯誤, 怎麼辦?
這時候就須要標記fromSite字段爲非必填, 用"?"標記:

interface Article {
    title: stirng;
    count: number;
    content:string;
    fromSite?: string; // 非必填
}

// 不會報錯
const article: Article = {
    title: '爲vue3學點typescript(2), 類型',
    count: 9999,
    content: 'xxx...',
}

用接口定義函數

接口不只能夠定義對象, 還能夠定義函數:

// 聲明接口
interface Core {
    (n:number, s:string):[number,string]
}

// 聲明函數遵循接口定義
const core:Core = (a,b)=>{
    return [a,b];
}

用接口定義類

先簡單看下如何給類定義接口, 後面的課程具體講類:

// 定義
interface Animate {
    head:number;
    body:number;
    foot:number;
    eat(food:string):void;
    say(word:string):string;
}

// implements
class Dog implements Animate{
    head=1;
    body=1;
    foot=1;
    eat(food){
        console.log(food);
    }
    say(word){
        return word;
    }
}

交叉類型(&)

交叉類型是將多個類型合併爲一個類型, 表示"而且"的關係,用&鏈接多個類型, 經常使用於對象合併:

interface A {a:number};
interface B {b:string};

const a:A = {a:1};
const b:B = {b:'1'};
const ab:A&B = {...a,...b};

聯合類型(|)

交叉類型也是將多個類型合併爲一個類型, 表示""的關係,用|鏈接多個類型:

function setWidth(el: HTMLElement, width: string | number) {
    el.style.width = 'number' === typeof width ? `${width}px` : width;
}

注意: 我這裏標記了el爲HTMLElement, 能夠在typescript的倉庫看到ts還定義了不少元素, 請自行瀏覽(不用背, 用的時候現查),
https://github.com/microsoft/...

總結

若是您看完了上面的全部知識點, 你就能夠開始動手造輪子練習了, 加油. 下面是我用ts造的輪子, 若是喜歡請幫忙點下star, 謝謝.

手勢庫: https://github.com/any86/any-...

命令式調用vue組件: https://github.com/any86/vue-...

工做中經常使用的一些代碼片斷: https://github.com/any86/usef...

一個mini的事件管理器: https://github.com/any86/any-...

相關文章
相關標籤/搜索