TypeScript Ramda prop 或返回类型

问题描述

我正在用 TypeScript 中的 Ramda 编写一个 Redux 选择器:

const getAvatar = pipe(
  getCurrentUsersProfile,propOr('/images/default-avatar.png','avatar'),);

getAvatar 的工具提示说它返回 unkNown

使用 prop 函数,我可以断言这样的返回类型:

const getCurrentUsersId = pipe(
  getUserProfileSlice,prop<'currentUsersId'>('currentUsersId'),);

我怎样才能知道 propOr 总是返回一个 string

解决方法

您可以显式键入 propOr 调用,并添加返回值 (stackblitz):

import { pipe,propOr } from 'ramda';

const getCurrentUsersProfile = () => {};

const getAvatar = pipe(
  getCurrentUsersProfile,propOr('/images/default-avatar.png','avatar') as (src: any) => string,);
, 我认为

propOr 从根本上很难输入——我认为说它总是返回一个字符串会破坏函数的意义。

该函数旨在在提供的对象不具有指定属性的情况下提供回退。对象的类型将满足以下三个条件之一:

  • TS 可以验证它是否拥有该属性
  • TS 可以验证它没有属性
  • TS 无法验证是否拥有该属性

在第一个或第二个条件中,TS 可以告诉您函数结果的类型,因此调用 propOr 几乎没有意义——我们已经知道它要么有,要么没有我们正在查询的属性。

问题在于输入第三个条件。如果我们在一个未知类型的对象上调用 propOr,propOr 应该返回什么类型?充其量我想它是像 unknown | T 这样的东西,它什么也不告诉我们,真的。如果我们无法验证对象在某个属性 T 处是否具有类型为 K 的值,那么我们就无法确定函数的结果是什么。

我能想到的最好的事情(我希望有人有更好的建议)是提供一个函数,该函数将始终将键值强制转换为我们想要的类型,例如在以下示例中(请原谅非柯里化函数):

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 可能 不返回字符串并说它总是不完全正确(尽管您可能完全乐意为您的代码接受这一点。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...