最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

TypeScript類型any never void和unknown使用場景區(qū)別

 更新時間:2022年10月08日 11:05:58   作者:進擊的大蔥  
這篇文章主要為大家介紹了TypeScript類型any never void和unknown使用場景區(qū)別,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

不知道初學(xué)TypeScript的同學(xué)會不會和我一樣被any,unknown,nevervoid這幾個類型搞得暈頭轉(zhuǎn)向呢?如果你也有同樣的困惑,那么就請跟著本篇文章徹底搞懂這四種類型的區(qū)別吧。

any

首先給大家介紹的是any類型,我相信一些從JavaScript轉(zhuǎn)TypeScript的同學(xué)一定不會對這個類型感到陌生,因為它是我們將JavaScript代碼重構(gòu)為TypeScript代碼的銀彈,甚至有些程序員由于過度依賴any類型活生生將TypeScript寫成了AnyScript。

用法

當我們將某個變量定義為any類型后,TypeScript將會跳過對這個變量的類型檢查:

let something: any = 'Hello World!' 
something = 18 // ok! ts不會管any的類型檢查
something = true // ok! ts不會管any的類型檢查

在上面的代碼中一般來說如果something被初始化為一個字符串類型后,是不可以被賦值為number或者boolean類型的,不過由于我們聲明了它的類型是any所以TypeScript就完全不管這個對象的類型檢查了。除了這個,你還可以隨意訪問這個any對象上面的任意屬性,即使它們不存在:

let something: any = 'Hello World!'
something.notExistMethod() // ok! 
something.notExistProperty.name() // ok!

在上面的代碼中我們可以訪問any類型對象的任意屬性,并且這個any是具有傳遞性的,也就是說something后面無論跟了多少個屬性訪問,它們的類型都是any。

使用場景

any一般的使用場景有下面這些:

  • 代碼從JS遷移到TS:這個時候使用any我們可以將重構(gòu)快速推進而不用陷入無邊無盡的類型錯誤里面去。這里值得一提的是any只能作為臨時過渡方案,我們最后的結(jié)果一定是確保代碼盡可能少any的出現(xiàn)
  • 我們不關(guān)心對象的類型:例如我們實現(xiàn)了一個print函數(shù),這個函數(shù)底層調(diào)用console.log,這個時候其實我們不需要關(guān)心傳進來的具體數(shù)據(jù)類型是什么,我們只需要一股腦將它傳遞給console.log函數(shù)即可,這個時候我們就可以將函數(shù)的參數(shù)類型設(shè)置為any

類型缺失或者補全困難:這種情況一般發(fā)生在我們使用了第三方JS編寫庫的時候,我們沒有辦法知道某個導(dǎo)出的函數(shù)的具體類型,這時我們需要定義一些全局的類型墊片:

// shim.d.ts
declare module "unknown-type-lib" {
  export function someFunction(input: string): any
}

注意:雖然any很方便,可是我們還是需要想辦法避免代碼中出現(xiàn)any類型,這是因為any跳過了所有的類型檢查,而這會給我們帶來一些潛在的安全問題。最壞的情況是整個代碼除了any沒有其它有意義的類型,這個時候還不如直接編寫JavaScript代碼來得實在,既然我們選擇了TypeScript,我們還是希望它可以真真實實為我們帶來收益的,因此當我們碰到一些很難編寫的類型時,最好的做法不是寫any,而是詢問一些資深的工程師或者網(wǎng)上查找資料來解決這個問題。

unknown

上面我們說到了any會跳過所有的類型問題,而這其實會為日后的代碼維護和開發(fā)埋下巨大的安全隱患。為了解決any的問題,TypeScript在3.0版本引入了unknown類型,它可以理解為類型安全的(type-safe)any。

用法

any一樣,任何類型都可以賦值給unknown類型的對象:

let vAny: any = 'Hello World!' // ok! any對象接受任何類型
let vUnknown: unknown = 'Hello World!' // ok! unknown對象接受任何類型的對象

any不一樣,unknown類型的對象不可以直接賦值給其它非unknownany類型的對象,并且不可以訪問上面的任何屬性:

let vAny: any = 'Hello World!'
let vUnknown: unknown = 'Hello World!'
let vNumberForAny: number = vAny // ok! any可以直接賦值給其它任意類型
let vNumberForUnknown: number = vUnknown // error! unknown不可以直接賦值給其它非any和unknown類型的對象
vAny.toLocaleLowerCase() // ok! any可以訪問所有的屬性
vUnknown.toLocaleLowerCase() // error! unknown對象不可以直接訪問上面的屬性

那么應(yīng)該怎樣才能使用unknown類型的變量呢?答案很簡單,那就是你需要先推斷出對象的類型,才能使用,推斷的方式有很多種,包括typeofas assertion等其他type guard方法:

let vUnknown: unknown = 'abc'
// 使用typeof推斷出vUnknown的類型是string
if (typeof vUnknown === 'string') {
    vUnknown.toLocaleUpperCase() // ok! 因為能進入這個if條件體就證明了vUnknown是字符串類型!
}
let vNumberForUnknown: number = vUnknown as number // unknown類型一定要使用as關(guān)鍵字轉(zhuǎn)換為number才可以賦值給number類型

使用場景

由于unknown基本可以替代any,所以在任何any適用的場景,都應(yīng)該優(yōu)先使用unknown。使用了unknown后,我們既允許某個對象儲存任意類型的變量,同時也要求別人在使用這個對象的時候一定要先進行類型推斷。

never

never不像前面那幾個類型一樣常用,甚至有些同學(xué)可能一開始壓根就不知道這個類型存在的意義是什么。我們知道TypeScript在解析我們的代碼時會對代碼進行類型推斷,并且在代碼流不斷深入的時候,類型會從較為寬泛的類型(例如any)一直推斷到較為具體的類型,而這么推斷下去是會有個終點,這個終點就是不存在的,不可能發(fā)生的類型,也就是類型系統(tǒng)的底部類型(bottom type),而never就是TypeScript的底部類型。

用法

never類型只接受never類型的對象,甚至萬金油any類型都不可以賦值給never類型。

let vAny: any = 1
let vNever: never =  vAny // error! never除了自己誰不都接受!

一般當我們想表示某個函數(shù)永遠不會返回時,可以使用never類型,例如下面的例子:

// 因為這個是無限循環(huán),我們可以使用never作為返回值表示它永遠不會返回
function foreverLoop(): never {
  while(true) {}
}
// 因為這個函數(shù)會拋出異常,所以也是不會返回的
function crashFunc(): never {
  throw new Error('this function will crash')
}

使用場景

never類型的一個最大的作用就是幫我們對類型進行exclusive check,例如下面這個例子:

interface QA {
    kind: 'qa'
    bug: number
}
interface Developer {
    kind: 'developer'
    hair: number
}
type TechDude = QA | Developer
function printTechDude(h: TechDude) {
    if (h.kind === 'qa') {
        console.log(h.bug)
    } else if (h.kind === 'developer') {
        console.log(h.hair)
    } else {
        let exclusiveCheck: never = h // 由于這個代碼永遠也到達不了,所以h的類型被自動推斷為never
    }
}

上面的代碼現(xiàn)在是沒有問題的,不過假如某一天我們新增了一個新的PM類型,而忘記在printTechDude函數(shù)里面處理這個新類型的話,上面的代碼會報錯:

interface QA {
    kind: 'qa'
    bug: number
}
interface Developer {
    kind: 'developer'
    hair: number
}
interface PM {
    kind: 'pm'
    features: number
}
// TechDude多了一個PM類型
type TechDude = QA | Developer | PM
function printTechDude(h: TechDude) {
    if (h.kind === 'qa') {
        console.log(h.bug)
    } else if (h.kind === 'developer') {
        console.log(h.hair)
    } else {
        let exclusiveCheck: never = h // error! 因為PM類型不可以賦值給never類型
    }
}

上面代碼報錯的原因是TechDude這個類型在else這個代碼體里面已經(jīng)被TypeScript收攏為PM類型,所以不再是never類型了。要去掉這個錯誤,我們需要在printTechDude函數(shù)里面額外加多一個else if(h.kind === 'pm')的判斷:

function printHuman(h: TechDude) {
    if (h.kind === 'qa') {
        console.log(h.bug)
    } else if (h.kind === 'developer') {
        console.log(h.hair)
    } else if (h.kind === 'pm') {
        console.log(h.features)
    }else {
        let exclusiveCheck: never = h
    }
}

也正是因為exclusive check的存在我們才可以在類型變化的時候及時發(fā)現(xiàn),避免問題留到了線上環(huán)境。

void

void其實可以理解為null和undefined的聯(lián)合類型,它表示空值。

用法

我們一般不會聲明某個值的類型為void,因為它表示這個值只能是undefined或者null(strictNullChecks沒被指定):

let vVoid: void = undefined

void一個更加常見的使用場景是表示某個函數(shù)沒有任何返回值:

function noReturnValue(): void {
  console.log('hello')
  // 代碼沒有任何返回值,所以這個函數(shù)的返回值是void
}

使用場景

這里只想說明一下voidnever的區(qū)別。void表示空值,也就是null或者undefined,而never則表示永遠都不會出現(xiàn)的值。

總結(jié)

本篇文章通過例子給大家介紹了TypeScript中幾個容易混淆的類型any,unknownnever void,希望能幫助有需要的人解答到疑惑,更多關(guān)于TypeScript類型使用場景的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • TypeScript Nim交替使用細節(jié)分析

    TypeScript Nim交替使用細節(jié)分析

    這篇文章主要為大家介紹了TypeScript Nim交替使用細節(jié)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • typescript 支持與本地調(diào)試配置詳解

    typescript 支持與本地調(diào)試配置詳解

    這篇文章主要為大家介紹了typescript 支持與本地調(diào)試配置詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • typescript type 分配條件類型示例詳解

    typescript type 分配條件類型示例詳解

    這篇文章主要為大家介紹了typescript type 分配條件類型示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • typescript快速上手的進階類型與技術(shù)

    typescript快速上手的進階類型與技術(shù)

    本文講述了typescript開發(fā)的一些高級的類型與技術(shù),算是對于基礎(chǔ)知識點的補充,具體內(nèi)容包括:比如元組、枚舉類、接口、泛型相關(guān)概念等。雖說是進階,但是內(nèi)容不算多也并不難理解。
    2022-12-12
  • typescript快速上手的基礎(chǔ)知識篇

    typescript快速上手的基礎(chǔ)知識篇

    靜態(tài)類型的typescript與傳統(tǒng)動態(tài)弱類型語言javascript不同,在執(zhí)行前會先編譯成javascript,因為它強大的type類型系統(tǒng)加持,能讓我們在編寫代碼時增加更多嚴謹?shù)南拗啤W⒁?,它并不是一門全新的語言,所以并沒有增加額外的學(xué)習(xí)成本
    2022-12-12
  • Three.js引入Cannon.js及使用示例詳解

    Three.js引入Cannon.js及使用示例詳解

    這篇文章主要為大家介紹了Three.js引入Cannon.js及使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • TypeScript?泛型接口具體使用實戰(zhàn)

    TypeScript?泛型接口具體使用實戰(zhàn)

    這篇文章主要為大家介紹了TypeScript?泛型接口具體使用實戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • TypeScript?類型級別示例介紹

    TypeScript?類型級別示例介紹

    這篇文章主要為大家介紹了TypeScript?類型級別示例介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • TypeScript實現(xiàn)十大排序算法之冒泡排序示例詳解

    TypeScript實現(xiàn)十大排序算法之冒泡排序示例詳解

    這篇文章主要為大家介紹了TypeScript實現(xiàn)十大排序算法之冒泡排序示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • TypeScript使用noImplicitAny實戰(zhàn)解析

    TypeScript使用noImplicitAny實戰(zhàn)解析

    這篇文章主要為大家介紹了TypeScript使用noImplicitAny實戰(zhàn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08

最新評論

南汇区| 安义县| 岗巴县| 景德镇市| 云南省| 古交市| 罗城| 崇礼县| 电白县| 衡水市| 嘉祥县| 昌吉市| 台山市| 通辽市| 咸丰县| 大方县| 商洛市| 清河县| 涞源县| 大港区| 阿巴嘎旗| 双流县| 个旧市| 桐乡市| 临安市| 石景山区| 北京市| 阜南县| 专栏| 原平市| 洪湖市| 隆回县| 涞源县| 南平市| 凤城市| 盈江县| 锡林浩特市| 南平市| 五台县| 无极县| 榆中县|