TypeScript Ramda propo返回类型

TypeScript Ramda propo返回类型,typescript,return-type,ramda.js,typescript-types,Typescript,Return Type,Ramda.js,Typescript Types,我正在用TypeScript中的Ramda编写一个Redux选择器: const getAvatar = pipe( getCurrentUsersProfile, propOr('/images/default-avatar.png', 'avatar'), ); getAvatar的工具提示显示它返回unknown 使用prop函数,我可以断言如下返回类型: const getCurrentUsersId = pipe( getUserProfileSlice, prop&

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

const getAvatar = pipe(
  getCurrentUsersProfile,
  propOr('/images/default-avatar.png', 'avatar'),
);
getAvatar
的工具提示显示它返回
unknown

使用
prop
函数,我可以断言如下返回类型:

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

我如何才能让它知道
propro
总是返回
字符串

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


我认为,propOr从根本上说是很难键入的,如果说它总是返回字符串,我认为,这会破坏函数的意义

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

  • TS可以验证它是否具有该属性
  • TS可以验证它不具有该属性
  • TS无法验证它是否具有该属性
在第一种或第二种情况下,TS可以告诉您函数结果的类型,因此调用propOr几乎没有意义——我们已经知道它具有或不具有我们正在查询的属性

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

我能想到的最好的办法(我希望有人有更好的建议)是提供一个函数,该函数总是将键处的值强制为我们想要的类型,例如在下面的示例中(请原谅未绑定的函数):

consthaskey=(k:k,o:any):o是U=>o.hasOwnProperty(k);
常量比例=(d:T,k:k,o:any,f:(x:any)=>T)=>hasKey(k,o)
? f(o[k])
:f(d);
const test=propo('/images/default avatar.png','avatar',{a:1},(s:any)=>`${s}`);

在本例中,
test
是string类型,但感觉非常笨拙。我想不出任何其他方法可以用可靠的类型来实现这一点@OriDriori提供类型提示的选项可以很好地工作,但我猜这会迫使typescript的手有一点-propOr可能不会返回字符串,并说它总是不完全正确(尽管您可能完全乐意接受这一点,实际上对于您的代码来说它是正确的)。

谢谢您的全面回答!你说过“propOr可能不会返回字符串”,但它总是会,对吗?我知道对象,并且知道对象的属性(如果存在)是字符串。我的退路是一条绳子。所以我可以保证它始终是一个字符串。即使退路与道具是不同的类型,也不应该有一种方法将其告知propOr吗?例如,这是一个字符串,或者-如果回退-一个数字?@J.hester我相信,不,它不会总是返回一个字符串-在
propo('a','prop',{prop:1})
它会返回一个数字的情况下。在您的情况下,
getUserProfile
可能总是返回一个具有属性“avatar”且类型始终为“string”的对象,但在这种情况下,
prop
可能是一个更有用的函数
import { pipe, propOr } from 'ramda';

const getCurrentUsersProfile = () => {};

const getAvatar = pipe(
  getCurrentUsersProfile,
  propOr('/images/default-avatar.png', 'avatar') as (src: any) => string,
);
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}`);