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 可能 不返回字符串并说它总是不完全正确(尽管你可能非常乐意接受它实际上对您的代码来说是这样的)。