Flowtype/Typescript 通用获取 属性
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: /* ! */): /* ! */ { ... }
编辑 2:
到目前为止我已经写了以下内容:
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]
的值类型。
Where get is a general purpose function for obj of any type. Can we annotate the code in a way that flow will check if obj has prop
你不能用 TypeScript 做到这一点。
Something with similar functionality as _.get
如果安全导航运算符可用,会容易得多:https://github.com/Microsoft/TypeScript/issues/16
然而,JavaScript 委员会需要继续努力,据我所知,遗憾的是它没有得到任何人的支持。
到那时我也做了a && a.b
等等
更多
我在清理其他人的代码时有时会用到的一个慢功能:
export function safe<T>(action: () => T): T | undefined {
try {
return action();
}
catch (ex) {
return undefined;
}
}
// Usage
let c = safe(()=>a.b.c);
你可以用 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];
}
或者制作可组合的东西。
有什么方法可以在流程或打字稿中正确输入检查以下代码吗?:
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: /* ! */): /* ! */ { ... }
编辑 2:
到目前为止我已经写了以下内容:
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]
的值类型。
Where get is a general purpose function for obj of any type. Can we annotate the code in a way that flow will check if obj has prop
你不能用 TypeScript 做到这一点。
Something with similar functionality as _.get
如果安全导航运算符可用,会容易得多:https://github.com/Microsoft/TypeScript/issues/16
然而,JavaScript 委员会需要继续努力,据我所知,遗憾的是它没有得到任何人的支持。
到那时我也做了a && a.b
等等
更多
我在清理其他人的代码时有时会用到的一个慢功能:
export function safe<T>(action: () => T): T | undefined {
try {
return action();
}
catch (ex) {
return undefined;
}
}
// Usage
let c = safe(()=>a.b.c);
你可以用 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];
}
或者制作可组合的东西。