欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ts?類型體操?Chainable?Options?可鏈?zhǔn)竭x項(xiàng)示例詳解

 更新時(shí)間:2022年09月16日 14:06:27   作者:盞燈  
這篇文章主要為大家介紹了ts?類型體操?Chainable?Options?可鏈?zhǔn)竭x項(xiàng)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

問題

在JavaScript我們通常會(huì)使用到可串聯(lián)(Chainable/Pipline)的函數(shù)構(gòu)造一個(gè)對(duì)象,但是在Typescript中,你能合理地給它賦上類型嗎?

題目是: 可以使用任何你喜歡的方式實(shí)現(xiàn)這個(gè)類型 - interface, type, 或者 class 都行。你需要提供兩個(gè)函數(shù)option(key, value)get()

option 中你需要使用提供的key和value來擴(kuò)展當(dāng)前的對(duì)象類型,通過 get()獲取最終結(jié)果。

注意: 你只需要在類型層面實(shí)現(xiàn)這個(gè)功能 - 不需要實(shí)現(xiàn)任何 ts/js 的實(shí)際邏輯。 你可以假設(shè)key只接受字符串而value接受任何類型,你只需要暴露它傳遞的類型而不需要進(jìn)行任何處理。同樣的key只會(huì)被使用一次。

例子是:

declare const config: Chainable
const result = config
    .option('foo', 123)
    .option('bar', { value: 'Hello World' })
    .option('name', 'type-challenges')
    .get()
// expect the type of the result to be:
interface Result {
    foo: number
    name: string
    bar: {
        value: string
    }
}

答案

type Chainable = {
  option(key: string, value: any): any
  get(): any
}

把這個(gè)any改成答案即可。作者要求我們做什么?需要實(shí)現(xiàn)兩個(gè)方法,一個(gè)是options(key, value),另一個(gè)是get()。

option(key, value): 必須在某處累加 keyvalue 的類型信息。累加操作必須持續(xù)進(jìn)行,直到調(diào)用get函數(shù)將累加的信息作為一個(gè)對(duì)象類型返回。

先看看提供的樣例:

const result1 = a
    .option('foo', 123)
    .option('bar', {value: 'Hello World'})
    .option('name', 'type-challenges')
    .get()
希望得到的是:
type Expectd1 = {
    foo: number,
    bar: {
        value: string
    },
    name: string
}

傳參

把option傳的key值和value值給對(duì)應(yīng)改了。所以我們把keyvalueany替換成類型參數(shù),以便ts可以推斷出它們的類型并將其分配給類型參數(shù):

type Chainable<T = {}> = {
  option<K, V>(key: K, value: V): any
  get(): any
}

我們現(xiàn)在有了關(guān)于keyvalue的類型信息。ts會(huì)將key推斷為字符串字面量類型, 而將value推斷為常見的類型。

例如: 調(diào)用option('foo', 123)將得出的類型為: key = 'foo‘ 和 value = number

我們有了信息后,把它存儲(chǔ)在哪里呢?它必須是一個(gè)在若干次方法調(diào)用中保持其狀態(tài)的地方。唯一的地方便是Chainable類型本身。

讓我們?yōu)?code>Chainable類型添加一個(gè)新的類型參數(shù)T,并且不能忘記默認(rèn)它是一個(gè)空對(duì)象。

type Chainable<T = {}> = {}

option部分

注意,我們希望option(key, value)返回Chainable類型本身(我們希望有可能進(jìn)行鏈?zhǔn)秸{(diào)用),但是要將類型信息累加到其類型參數(shù)中。

那么我們使用&來將新的類型添加到累加器中:

type Chainable&lt;T = {}&gt; = {
    option&lt;K, V&gt;(key: K, value: V): Chainable&lt;T &amp; { [k in K] : V }&gt;;
    get(): any
}

這里值得提一下為什么是 { [k in K] : V }, 直接寫 { K : V } 不行嗎?為什么還要in一下?

由于K是類型,類型是不能直接當(dāng)成key的,在ts中對(duì)象如若想要以類型來當(dāng)key也就是類型當(dāng)鍵,要[k in K]這樣寫才行。

比如說: 定義一個(gè)類型key value這種字面量的對(duì)象,當(dāng)時(shí)必須value是string類型。

type a<K extends string> = {[k in K]: string}
type b = a<>
const c:b = {
  a: 'c'
}

那接上面,所以這個(gè)K必須是string類型,js中字面量的key必須是string類型。所以改一下:

type Chainable<T = {}> = {
    option<K extends string, V>(key: K, value: V): Chainable<T & { [k in K] : V }>;
    get(): any
}

get

那么,這個(gè)get()函數(shù)調(diào)用的時(shí)候,應(yīng)該返回什么呢,它必須從Chainable返回類型參數(shù)T,也就是option(key, value)鏈?zhǔn)秸{(diào)用所得到的的這么一個(gè)對(duì)象,也就是option(key, value)一直點(diǎn)調(diào)用的整體類型信息,那么就是傳入的這個(gè)參數(shù)也就是T本身。

type Chainable<T = {}> = {
    option<K extends string, V>(key: K, value: V): Chainable<T & { [k in K] : V }>;
    get(): T
}

那么這樣就完成了嗎?我們來看一下測(cè)試結(jié)果

怎么還有紅色波浪線,我們來看看

const result2 = a
  .option('name', 'another name')
  // @ts-expect-error
  .option('name', 'last name')
  .get()

哦,原來是這個(gè)對(duì)象中key相同的了,就不用再點(diǎn)調(diào)用下去了,直接省略。那么也就是說這個(gè)key的類型要控制一下,當(dāng)判斷到這個(gè)key已經(jīng)存在了,我們就略過

type Chainable<T = {}> = {
    option<K extends string, V>(key: K extends keyof T ? never : K, value: V): Chainable<T & { [k in K] : V }>;
    get(): T
}

單拎出來看看

key: K extends keyof T ? never : K

至此,完成這一道題!

以上就是ts 類型體操 Chainable Options 可鏈?zhǔn)竭x項(xiàng)示例詳解的詳細(xì)內(nèi)容,更多關(guān)于ts 類型Chainable Options的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論