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ù),否則我敢打賭這真的沒有必要。

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 effect
或return type
更清潔)
添加回答
舉報