【问题标题】:TypeScript Ramda propOr return typeTypeScript Ramda prop或返回类型
【发布时间】:2021-04-19 06:53:48
【问题描述】:

我正在 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

【问题讨论】:

    标签: typescript return-type ramda.js typescript-types


    【解决方案1】:

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

    import { pipe, propOr } from 'ramda';
    
    const getCurrentUsersProfile = () => {};
    
    const getAvatar = pipe(
      getCurrentUsersProfile,
      propOr('/images/default-avatar.png', 'avatar') as (src: any) => string,
    );
    

    【讨论】:

      【解决方案2】:

      propOr 我认为从根本上难以输入 - 我认为说它总是返回一个字符串会破坏函数的要点。

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

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

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

      问题在于第三个条件的输入。如果我们在一个未知类型的对象上调用 propOr,propOr 应该返回什么类型?充其量我想它就像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 可能 不返回字符串并说它总是不完全正确(尽管你可能非常乐意接受它实际上对您的代码来说是这样的)。

      【讨论】:

      • 感谢您的全面回答!你说“propOr 可能不返回字符串”,但它总是会的,对吧?我知道该对象并且知道该对象的属性(如果存在)是一个字符串。我的后备是一个字符串。所以我可以保证它总是一个字符串。即使后备与 prop 的类型不同,难道不应该有办法告诉 propOr 吗?例如,这是一个字符串还是 - 如果回退 - 一个数字?
      • @J.Hesters 我相信,不,它不会总是返回一个字符串 - 在propOr('a', 'prop', {prop: 1}) 它会返回一个数字的情况下。在您的情况下,getUserProfile 可能始终返回一个具有属性“avatar”并且始终为“字符串”类型的对象,但在这种情况下,prop 可能是一个更有用的函数
      猜你喜欢
      • 2018-03-01
      • 2019-03-02
      • 2021-10-17
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多