[英]Flowtype/Typescript general purpose get property
有什么方法可以在流或打字稿中正確鍵入以下代碼?
type A = {
x: string
}
type B = {
y: string
}
function get(obj, prop) {
return obj[prop];
}
const a: A = { x: 'x' }
const b: B = { y: 'y' }
get(a, 'x') // should type check
get(b, 'y') // should type check
get(a, 'y') // should NOT type check
get(b, 'x') // should NOT type check
其中, get
是任何類型的obj
的通用函數。 我們是否可以通過流程將檢查obj
是否具有prop
的方式注釋代碼?
主要用例是為深層屬性編寫通用的get函數。 具有與_.get
類似的功能。 我正在努力避免這種情況:
if (a && a.b && a.b.c && a.b.c.d === 'blah') { ... }
如@vkurchatkin所述,我們可以使用$Keys
。 但是我只能將其與深度為1級的getter函數一起使用。 我們如何鍵入以下函數:
get<T: {}>(obj: T, prop1: $Keys<T>, prop2: /* ! */): /* ! */ { ... }
到目前為止,我已經寫了以下內容:
type A = {
x: B
}
type B = {
y: string
}
type GetDeep<T: {}, U, V> = Helper<T, U, V, Get<T, U>, Get<U, V>>
type Helper<T, U, V, W, X> = (obj: T, a: $Keys<T>, b: $Keys<U>) => V
type Get<T, U> = (obj: T, a: $Keys<T>) => U;
// NOTE: here if I replace GetDeep<*, B, *> with GetDeep<*, *, *>
// then it wrongly type checks everything
const getDeep: GetDeep<*, B, *> = (obj, a, b) => {
return obj[a][b];
}
var va: A = {
x: {y: 'abc'}
}
getDeep(va, 'x', 'y'); // ok
getDeep(va, 'x', 'z'); // error
看起來像type Get<T, U> = (obj: T, a: $Keys<T>) => U
, U
不是obj[a]
值的類型。
您可以使用Flow來做到這一點:
function get<T: {}>(obj: T, prop: $Keys<T>) {
return obj[prop];
}
不幸的是,返回的類型被推斷為any
。 Flow目前正在開發$PropertyType
,因此我相信將來應該可以(它無法按預期運行):
function get<T: {}, P: $Keys<T>>(obj: T, prop: P): $PropertyType<T, P> {
return obj[prop];
}
使用這種類型,您將可以深入兩個層次:
function getDeep<
T: {},
P: $Keys<T>,
R: $PropertyType<T, P>,
P2: $Keys<R>
>(obj: T, a: P, b: P2): $PropertyType<R, P2> {
return obj[a][b];
}
或使某些東西變得可組合。
其中,get是任何類型的obj的通用函數。 我們是否可以通過以下方式對代碼進行注釋,即流程將檢查obj是否具有prop
您不能使用TypeScript做到這一點。
具有與_.get類似的功能
如果可以使用安全的導航操作符,將會容易得多: https : //github.com/Microsoft/TypeScript/issues/16
但是JavaScript委員會需要繼續努力,據我所知,可悲的是它沒有受到任何人的擁護。
直到那時,我還完成a && ab
等。
我在清理其他人的代碼時有時會使用的慢速功能:
export function safe<T>(action: () => T): T | undefined {
try {
return action();
}
catch (ex) {
return undefined;
}
}
// Usage
let c = safe(()=>a.b.c);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.