TypeScript Ramda propOr return 类型
TypeScript Ramda propOr return type
我正在使用 TypeScript 中的 Ramda 编写 Redux 选择器:
const getAvatar = pipe(
getCurrentUsersProfile,
propOr('/images/default-avatar.png', 'avatar'),
);
getAvatar
的工具提示说 returns unknown
。
使用 prop
函数,我可以断言一个 return 类型,如下所示:
const getCurrentUsersId = pipe(
getUserProfileSlice,
prop<'currentUsersId'>('currentUsersId'),
);
我如何让它知道 propOr
总是 return 是 string
?
您可以显式键入 propOr
调用,并添加 return 值 (stackblitz):
import { pipe, propOr } from 'ramda';
const getCurrentUsersProfile = () => {};
const getAvatar = pipe(
getCurrentUsersProfile,
propOr('/images/default-avatar.png', 'avatar') as (src: any) => string,
);
propOr
是,我认为,从根本上说很难打字 - 说它总是 return 是一个字符串,我认为,这会打败函数的意义。
该函数旨在在提供的对象没有指定的 属性 的情况下提供回退。对象的类型将满足三个条件之一:
- TS 可以验证它具有 属性
- TS 可以验证它没有 属性
- TS 无法验证是否有 属性
在第一种或第二种情况下,TS 可以告诉您函数结果的类型,因此调用 propOr 几乎没有意义 - 我们已经知道它可以或不可以有我们正在查询的属性。
问题在于第三个条件的输入。如果我们在未知类型的对象上调用 propOr,那么 propOr return 应该是什么类型?充其量我认为它是 unknown | T
之类的东西,它实际上什么也没告诉我们。如果我们无法验证该对象在某些 属性 K
处将具有类型 T
的值,那么我们无法说出该函数的结果是什么。
我能想到的最好的事情(我希望有人有更好的建议)是提供一个函数,它总是将键的值强制转换为我们想要的类型,例如在下面的例子中(原谅未柯里化的函数):
const hasKey = <K extends PropertyKey, T, U extends Record<K, U>>(k: K, o: any): o is U => o.hasOwnProperty(k);
const propOr = <K extends PropertyKey, T>(d: T, k: K, o: any, f: (x: any) => T) => hasKey(k, o)
? f(o[k])
: f(d);
const test = propOr<'avatar', string>('/images/default-avatar.png', 'avatar', { a: 1 }, (s: any) => `${s}`);
在这个实例中,test
是字符串类型,但感觉很笨重。我想不出任何其他方法来使用可靠的类型来做到这一点。 @OriDriori 提供类型提示的选项可以正常工作,但我猜它有点强迫打字稿的手 - propOr may not return a string 并说它总是会是不完全正确(尽管您可能非常乐意接受您的代码实际上会接受这一点)。
我正在使用 TypeScript 中的 Ramda 编写 Redux 选择器:
const getAvatar = pipe(
getCurrentUsersProfile,
propOr('/images/default-avatar.png', 'avatar'),
);
getAvatar
的工具提示说 returns unknown
。
使用 prop
函数,我可以断言一个 return 类型,如下所示:
const getCurrentUsersId = pipe(
getUserProfileSlice,
prop<'currentUsersId'>('currentUsersId'),
);
我如何让它知道 propOr
总是 return 是 string
?
您可以显式键入 propOr
调用,并添加 return 值 (stackblitz):
import { pipe, propOr } from 'ramda';
const getCurrentUsersProfile = () => {};
const getAvatar = pipe(
getCurrentUsersProfile,
propOr('/images/default-avatar.png', 'avatar') as (src: any) => string,
);
propOr
是,我认为,从根本上说很难打字 - 说它总是 return 是一个字符串,我认为,这会打败函数的意义。
该函数旨在在提供的对象没有指定的 属性 的情况下提供回退。对象的类型将满足三个条件之一:
- TS 可以验证它具有 属性
- TS 可以验证它没有 属性
- TS 无法验证是否有 属性
在第一种或第二种情况下,TS 可以告诉您函数结果的类型,因此调用 propOr 几乎没有意义 - 我们已经知道它可以或不可以有我们正在查询的属性。
问题在于第三个条件的输入。如果我们在未知类型的对象上调用 propOr,那么 propOr return 应该是什么类型?充其量我认为它是 unknown | T
之类的东西,它实际上什么也没告诉我们。如果我们无法验证该对象在某些 属性 K
处将具有类型 T
的值,那么我们无法说出该函数的结果是什么。
我能想到的最好的事情(我希望有人有更好的建议)是提供一个函数,它总是将键的值强制转换为我们想要的类型,例如在下面的例子中(原谅未柯里化的函数):
const hasKey = <K extends PropertyKey, T, U extends Record<K, U>>(k: K, o: any): o is U => o.hasOwnProperty(k);
const propOr = <K extends PropertyKey, T>(d: T, k: K, o: any, f: (x: any) => T) => hasKey(k, o)
? f(o[k])
: f(d);
const test = propOr<'avatar', string>('/images/default-avatar.png', 'avatar', { a: 1 }, (s: any) => `${s}`);
在这个实例中,test
是字符串类型,但感觉很笨重。我想不出任何其他方法来使用可靠的类型来做到这一点。 @OriDriori 提供类型提示的选项可以正常工作,但我猜它有点强迫打字稿的手 - propOr may not return a string 并说它总是会是不完全正确(尽管您可能非常乐意接受您的代码实际上会接受这一点)。