2

我正在使用 Ramda.js 和 Typescript。为了从对象中获取一些值,我使用lensPath

例子:

export interface Store {
    foo: {
       bar: string;
    };
}

const store: Store = {
  foo: {
    bar: 'baz'
  }
};
const fooBarLens = R.lensPath(['foo', 'bar']);

不幸的是,如果我将通过我的 WebStorm 进行一些重构并将属性重命名barbazin class Store,那么函数fooBarLens将停止工作。

但是如果在重构之前我会重写这个函数fooBarLens,比如:

const fooBarLens = (s) => s.foo.bar;

然后重构将正常工作。

如何在lensPath不硬编码属性名称的情况下重写 using 和其他 Ramda 函数并避免重构问题?

4

1 回答 1

4

我不认为有一个很好的解决方案。这是使用基于字符串的 API 的权衡之一。我见过的许多重构工具还提供重命名字符串和注释中的属性,这可能就足够了,特别是如果它一个接一个地引导您浏览这些字符串并为您提供决定。

但是一种技术使这变得更容易:将数据模型的处理集中在一个模块中。如果您必须在整个代码库中更改此类代码,它可能会变得很难看:

const phone = view(lensPath(['contact', 'phones', 'primary'], user);

如果您的用户模块公开phoneLens并且您的代码只是

const phone = view(phoneLens, user)

然后,当您的模型更改时,您可以在该位置进行切换

const phoneLens = lensPath(['contact', 'phone', 'primary'])

const phoneLens = lensPath(['contacts', 'telephone', 0])

无需更改其余代码。


请记住,在 JavaScript 中,store.foo.bar格式实际上并不是核心。它只是更基本store['foo']['bar']版本的语法糖。重构工具有朝一日可能会赶上这种理解,如果他们还没有这样做的话。

于 2019-06-12T12:17:55.270 回答