第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

處理 TypeScript 中類型改變的副作用

處理 TypeScript 中類型改變的副作用

開滿天機 2022-12-02 16:51:07
這更像是一個關(guān)于如何處理在TypeScript. 我知道并且非常同意這個概念,即功能應(yīng)該盡可能少的副作用,如果有的話。但有時,希望就地更改對象(及其類型),而不是使用另一種靜態(tài)類型創(chuàng)建它的新副本。我最常遇到的原因是可讀性、效率或減少行數(shù)。由于我原來的例子過于復雜和過于復雜,這里有一個(希望如此)非?;镜睦樱簍ype KeyList = 'list' | 'of' | 'some' | 'keys';// Original type (e.g. loaded from a JSON file)interface Mappable {    source: { [K in KeyList]: SomeNestedObject },    sourceOrder: KeyList[];}// Mapped Type (mapped for easier access)interface Mapped {    source: { [K in KeyList]: SomeNestedObject },    sourceOrder: SomeDeepObject[];}// What I have to do to keep suggestions and strict types all the wayconst json: Mappable = JSON.parse(data); // ignoring validation for nowconst mapped: Mapped = toMappedData(json);// What I would like to toconst mapped: Mappable = JSON.parse(data);mapData(mapped); // mapped is now of type Mapped原因,為什么我想同時改變對象屬性和它的類型可能是:該json對象非常大,在內(nèi)存中擁有它的 2 個副本會適得其反json將對象深拷貝到對象mapped中非常麻煩我不相信“我想做什么”下的代碼可讀性很強,不管它是否工作。我正在尋找一種干凈且類型安全的方法來解決此問題?;蛘撸蛘撸ㄗh或想法來擴展打字稿的功能以解決此問題。非常感謝對此的任何建議、想法和評論!也許我對此太深入了,看不到真正簡單的解決方案。
查看完整描述

2 回答

?
墨色風雨

TA貢獻1853條經(jīng)驗 獲得超6個贊

我不認為你想做什么是可能的。您要求打字稿更改變量類型作為副作用。但這會帶來各種并發(fā)癥。


如果mapData函數(shù)有條件地運行怎么辦?


const mapped: Mappable = JSON.parse(data);

if (Math.random() > 0.5) {

  mapData(mapped); // mapped is now of type Mapped

}

// What type is `mapped` here?

或者,如果您在轉(zhuǎn)換之前傳遞對此對象的引用怎么辦?


function doAsyncStuff(obj: Mappable) {}

doAsyncStuff(mapped)

mapData(mapped)

// Then later, doAsyncStuff(obj) runs but `obj` is a different type than expected

我認為你能在這里得到的最接近的是一個轉(zhuǎn)換為中間類型的類型保護,它支持轉(zhuǎn)換前類型和轉(zhuǎn)換后類型的聯(lián)合,你可以在其中實際進行轉(zhuǎn)換。


interface A {

  foo: string

}


interface B {

  foo: string

  bar: string

}


interface A2B {

  foo: string

  bar?: string

}


function transform(obj: A): obj is B {

  const transitionObj: A2B = obj

  transitionObj.bar = "abc" // Mutate obj in place from type A to type B

  return true

}


const obj: A = { foo: 'foo' }

if (transform(obj)) {

  obj // type is B in this scope

}

obj // but obj is still type A here, which could lead to bugs.

但是,如果您實際上在該條件之外使用objas 類型A,那么這可能會導致運行時錯誤,因為類型是錯誤的。所以帶有副作用的類型保護函數(shù)也是一個非常糟糕的主意,因為類型保護可以讓你覆蓋類型腳本的正常輸入。


我真的認為你已經(jīng)在這里做了最好的方法,特別是如果輸出類型與輸入類型不同。將新對象不可變地構(gòu)造為新類型。


const mapped: Mapped = toMappedData(json);

如果性能或內(nèi)存是一個大問題,那么您可能不得不為此犧牲類型安全。編寫健壯的單元測試,將其投射到任何單元測試,添加關(guān)于那里發(fā)生的事情的非常突出的評論。但是除非您一次處理數(shù)百 MB 的數(shù)據(jù),否則我敢打賭這真的沒有必要。


查看完整回答
反對 回復 2022-12-02
?
梵蒂岡之花

TA貢獻1900條經(jīng)驗 獲得超5個贊

我目前所做的方式是:


type KeyList = 'list' | 'of' | 'some' | 'keys';


// Merged the types to keep the code a little shorter

// Also makes clear, that I don't alter the type's structure

interface MyType<M ext boolean = true> {

    source: { [K in KeyList]: SomeNestedObject },

    sourceOrder: (M ? SomeNestedObject : (KeyList | SomeNestedObject))[];

}


function mapData(data: MyType<true>): MyType {

    const { source, sourceOrder } = data.sourceOrder

    for (let i = 0; i < sourceOrder.length; i++) {

        if (typeof sourceOrder[i] == 'string') {

            sourceOrder[i] = source[sourceOrder[i]];

        }

    }


    return (data as unknown) as MyType;

}


const json: MyType<true> = JSON.parse(data);

const mapped: MyType = mapData(json);


// mapped now references json instead of being a clone

我不喜歡這種方法的地方:

  • 它不是類型安全的。打字稿無法檢查我是否正確地改變了類型

    • 因此,我必須轉(zhuǎn)換為未知,這并不理想

  • json類型不那么嚴格。可能會對代碼建議產(chǎn)生負面影響

  • 該功能有一個side effect以及一個return type(排他性side effectreturn type更清潔)


查看完整回答
反對 回復 2022-12-02
  • 2 回答
  • 0 關(guān)注
  • 129 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號