成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

殺手級(jí)的TypeScript功能:const斷言

chengtao1633 / 2226人閱讀

摘要:斷言官方文檔中給出了這樣的解釋引入了一個(gè)名為斷言的字面值的新構(gòu)造。在中,標(biāo)準(zhǔn)做法是從名為的函數(shù)創(chuàng)建操作。如果我們有一個(gè)用于設(shè)置小時(shí)數(shù)組的類型,它可能看起來像這樣在之前,擴(kuò)展會(huì)使上述操作的字面量屬性更加通用,因?yàn)樗鼈兪强梢孕薷牡摹?/p>

翻譯:瘋狂的技術(shù)宅

blog.logrocket.com/const-asser…

我發(fā)現(xiàn)官方的 TypeScript 文檔非常有用,但是總覺得有點(diǎn)過于學(xué)術(shù)化并且枯燥無味。每當(dāng)我發(fā)現(xiàn)一個(gè)新功能時(shí),我想要知道這個(gè)功能究竟能夠解決什么問題而不是長篇大論。

在我看來,const assertions 是 TypeScript 3.4 的殺手級(jí)新功能,正如我稍后將要解釋的,我們可以用這個(gè)新功能省略很多繁瑣的類型聲明。

const 斷言
const x = { text: "hello" } as const;

官方文檔中給出了這樣的解釋:

TypeScript 3.4 引入了一個(gè)名為 const 斷言的字面值的新構(gòu)造。它的語法是一個(gè)類型斷言,用 const 代替類型名稱(例如 123 as const)斷言構(gòu)造新的文字表達(dá)式時(shí),我們可以向語言發(fā)出以下信號(hào):

該表達(dá)式中的字面類型不應(yīng)被擴(kuò)展(例如:不能從“hello”轉(zhuǎn)換為字符串)

對象字面量獲取只讀屬性

數(shù)組文字成為只讀元組

感覺有點(diǎn)枯燥,還有點(diǎn)混亂。讓我們來各個(gè)擊破。

沒有類型擴(kuò)展的字面類型

并不是每個(gè)人都知道類型擴(kuò)展,并且由于某些意外行為而首次發(fā)現(xiàn)它時(shí)都會(huì)覺得意外。

當(dāng)我們使用關(guān)鍵字 const 聲明一個(gè)字面量時(shí),類型是等號(hào)右邊的文字,例如:

const x = "x"; // x has the type "x"

const 關(guān)鍵字確保不會(huì)發(fā)生對變量進(jìn)行重新分配,并且只保證該字面量的嚴(yán)格類型。

但是如果我們用 let 而不是 const, 那么該變量會(huì)被重新分配,并且類型會(huì)被擴(kuò)展為字符串類型,如下所示:

let x = "x"; // x has the type string;

以下是兩個(gè)不同的聲明:

const x = "x"; // has the type "x" 
let y = "x";   // has the type string

y 被擴(kuò)展為更通用的類型,并允許將其重新分配給該類型的其他值,而變量 x 只能具有 "x"的值。

用新的 const 功能,我可以這樣做:

let y = "x" as const; // y has type "x"`
對象字面量獲取只讀屬性

在 Typescript 3.4 之前,類型擴(kuò)展發(fā)生在對象字面量中:

const action = { type: "INCREMENT", } // has type { type: string }

即使我們將 action 聲明為 const,仍然可以重新分配 type 屬性,因此,該屬性被擴(kuò)展成了字符串類型。

這看上去令人覺得不是那么有用,所以讓我們換一個(gè)更好的例子。

如果你熟悉 Redux,就可能會(huì)發(fā)現(xiàn)上面的 action 變量可以用作 Redux action。如果你不知道 Redux 我來簡單解釋一下,Redux 是一個(gè)全局不可變的 state 存儲(chǔ)。通過向所謂的 reducers 發(fā)送動(dòng)作來修改狀態(tài)。 reducers 是純函數(shù),它在調(diào)度每個(gè) action 后返回全局狀態(tài)的新更新版本,以反映 acion 中指定的修改。

在 Redux 中,標(biāo)準(zhǔn)做法是從名為 action creators 的函數(shù)創(chuàng)建操作。 action creators 只是純函數(shù),它返回 Redux操作對象字面量以及提供給函數(shù)的所有參數(shù)。

用一個(gè)例子可以更好地說明這一點(diǎn)。應(yīng)用程序可能需要一個(gè)全局 count 屬性,為了更新這個(gè) count 屬性,我們可以調(diào)度類型為 "SET_COUNT" 的動(dòng)作,它只是將全局 count 屬性設(shè)置為一個(gè)新的值,這是一個(gè)字面對象屬性。這個(gè) action 的 action creator 將是一個(gè)函數(shù),它接受一個(gè)數(shù)字作為參數(shù),并返回一個(gè)具有屬性為 type、值為 SET_COUNT 和類型為 number 的 payload 屬性的對象,它將指定 count 的新值:

const setCount = (n: number) => {
  return {
    type: "SET_COUNT",
    payload: n,
  }
}

const action = setCount(3)
// action has type
// { type: string, payload: number }

從上面顯示的代碼中可以看出,type 屬性已經(jīng)被擴(kuò)展為 string 類型而不再是 SET_COUNT。這不是很安全的類型,我們可以保證的是 type 是一個(gè)字符串。 redux 中的每個(gè) action 都有一個(gè) type 屬性,它是一個(gè)字符串。

這不是很好,如果我們想要利用 type 屬性上的可區(qū)分聯(lián)合的話,那么在 TypeScript 3.4 之前,則需要為每個(gè) action 聲明一個(gè)接口或類型:

interface SetCount {
  type: "SET_COUNT";
  payload: number;
}

const setCount = (n: number): SetCount => {
  return {
    type: "SET_COUNT",
    payload: n,
  }
}

const action = setCount(3)
// action has type SetCount

這確實(shí)增加了編寫 Redux action 和 reducers 的負(fù)擔(dān),但我們可以通過添加一個(gè) const assertion 來解決這個(gè)問題:

const setCount = (n: number) => {
  return <const>{
    type: "SET_COUNT",
    payload: n
  }
}

const action = setCount(3);
// action has type
//  { readonly type: "SET_COUNT"; readonly payload: number };

你會(huì)注意到從 setCount 推斷的類型已經(jīng)在每個(gè)屬性中附加了 readonly 修飾符,正如文檔的項(xiàng)目符號(hào)所述。

這就是所發(fā)生的事情:

{
  readonly type: "SET_COUNT";
  readonly payload: number
};

action 中的每個(gè)字面量都被添加了 readonly 修飾符。

在 redux 中,我們創(chuàng)建了一個(gè)接受 action 的聯(lián)合,reducer 函數(shù)可以通過這種操作來獲得良好的類型安全性。在 TypeScript 3.4 之前,我們會(huì)這樣做:

interface SetCount {
  type: "SET_COUNT";
  payload: number;
}

interface ResetCount {
  type: "RESET_COUNT";
}

const setCount = (n: number): SetCount => {
  return {
    type: "SET_COUNT",
    payload: n,
  }
}

const resetCount = (): ResetCount => {
  return {
    type: "RESET_COUNT",
  }
}

type CountActions = SetCount | ResetCount

我們創(chuàng)建了兩個(gè)接口 RESET_COUNTSET_COUNT 來對兩個(gè) resetCountsetCount 的返回類型進(jìn)行歸類。

CountActions 是這兩個(gè)接口的聯(lián)合。

使用 const assertions,我們可以通過使用 const、 ReturnTypetypeof 的組合來消除聲明這些接口的需要:

const setCount = (n: number) => {
  return <const>{
    type: "SET_COUNT",
    payload: n
  }
}

const resetCount = () => {
  return <const>{
    type: "RESET_COUNT"
  }
}

type CountActions = ReturnType<typeof setCount> | ReturnType<typeof resetCount>;

我們從 action creator 函數(shù) setCountresetCount 的返回類型中推斷出一個(gè)很好的 action 聯(lián)合。

數(shù)組字面量成為只讀元組

在 TypeScript 3.4 之前,聲明一個(gè)字面量數(shù)組將被擴(kuò)展并且可以修改。

使用 const,我們可以將字面量鎖定為其顯式值,也不允許修改。

如果我們有一個(gè)用于設(shè)置小時(shí)數(shù)組的 redux action 類型,它可能看起來像這樣:

const action = {
  type: "SET_HOURS",
  payload: [8, 12, 5, 8],
}
//  { type: string; payload: number[]; }

action.payload.push(12) // no error

在 TypeScript 3.4 之前,擴(kuò)展會(huì)使上述操作的字面量屬性更加通用,因?yàn)樗鼈兪强梢孕薷牡摹?/p>

如果我們將 const 應(yīng)用于對象字面量,那么就可以很好地控制所有內(nèi)容:

const action = <const>{
  type: "SET_HOURS",
  payload: [8, 12, 5, 8]
}

// {
//  readonly type: "SET_HOURS";
//  readonly payload: readonly [8, 12, 5, 8];
// }

action.payload.push(12);  // error - Property "push" does not exist on type "readonly [8, 12, 5, 8]".

這里發(fā)生的事情恰恰是文檔的要點(diǎn):

payload 數(shù)組確實(shí)是 [8,12,5,8] 的“只讀”元組(不過我并沒有從文檔中看到這方面的說明)。

結(jié)論

我用以下代碼總結(jié)以上所有內(nèi)容:

let obj = {
  x: 10,
  y: [20, 30],
  z: {
    a:
      {  b: 42 }
  } 
} as const;

對應(yīng)于:

let obj: {
  readonly x: 10;
  readonly y: readonly [20, 30];
  readonly z: {
    readonly a: {
      readonly b: 42;
    };
  };
};

在這里,我可以推斷出類型,而不是去編寫多余的樣板類型。這對于 redux 特別有用。

歡迎關(guān)注前端公眾號(hào):前端先鋒,獲取「前端工程化實(shí)用工具包」

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/6967.html

相關(guān)文章

  • TypeScript 初識(shí) - 變量

    摘要:通常會(huì)定義為函數(shù)的返回值一個(gè)類型的變量是沒有生命用處的,因?yàn)轭愋偷淖兞恐荒苜x值為。和有一些區(qū)別的,函數(shù)沒有返回值時(shí)返回類型為的方法,即使沒有寫明語句,也會(huì)在函數(shù)執(zhí)行完的時(shí)候,隱式地返回一個(gè)類型。中新增加的變量聲明方式。 類型注解 類型注解使用 :TypeAnnotation 語法。類型聲明空間中可用的任何內(nèi)容都可以用作類型注解。 const num: number = 123; fun...

    dinfer 評論0 收藏0
  • TypeScript 2.7 記錄

    摘要:版本記錄針對版本的特性作專門的實(shí)例,希望能加深理解。這種情況下添加類型屬性被間接初始化了例如構(gòu)造函數(shù)中調(diào)用一個(gè)方法,更改了屬性的值。這種情況下我們可以使用顯式賦值斷言修飾符號(hào)來幫助類型系統(tǒng)識(shí)別類型。 TypeScript 2.7版本記錄 針對ts 2.7版本的特性作專門的實(shí)例,希望能加深理解。實(shí)例github地址 官方日志文檔 增加常量聲明的屬性的支持(Constant-named ...

    2bdenny 評論0 收藏0
  • 精讀《Typescript2.0 - 2.9》

    摘要:比如或者都會(huì)導(dǎo)致函數(shù)返回值類型時(shí)。和特性一樣,等于是函數(shù)返回值中的或。注意對比下面的寫法對于,它的返回值是可迭代的對象,并且每個(gè)類型都是或者。首先是不支持方法重載的,是支持的,而類型系統(tǒng)一定程度在對標(biāo),當(dāng)然要支持這個(gè)功能。 1 引言 精讀原文是 typescript 2.0-2.9 的文檔: 2.0-2.8,2.9 草案. 我發(fā)現(xiàn),許多寫了一年以上 Typescript 開發(fā)者,對 T...

    william 評論0 收藏0
  • typeScript學(xué)習(xí)筆記

    摘要:聯(lián)合類型,指賦值的時(shí)候可以是聯(lián)合類型中的某一個(gè)。任意屬性允許創(chuàng)建對象的時(shí)候,定義接口中沒有的屬性。常見的類型推論,還提現(xiàn)在函數(shù)表達(dá)式中。 typeScript是什么? TypeScript 是 JavaScript 的一個(gè)超集,主要提供了類型系統(tǒng)和對 ES6 的支持 安裝typeScript npm install -g typeScript 安裝完成查看版本: tsc -v typ...

    Guakin_Huang 評論0 收藏0
  • typescript - 一種思維方式

    摘要:怎么影響了我的思考方式對前端開發(fā)者來說,能強(qiáng)化了面向接口編程這一理念。使用的過程就是在加深理解的過程,確實(shí)面向接口編程天然和靜態(tài)類型更為親密。 電影《降臨》中有一個(gè)觀點(diǎn),語言會(huì)影響人的思維方式,對于前端工程師來說,使用 typescript 開發(fā)無疑就是在嘗試換一種思維方式做事情。 其實(shí)直到最近,我才開始系統(tǒng)的學(xué)習(xí) typescript ,前后大概花了一個(gè)月左右的時(shí)間。在這之前,我也在...

    CKJOKER 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<