如何在不对属性名称进行硬编码的情况下重写代码?

时间:2019-06-12 08:05:08

标签: typescript refactoring ramda.js

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

示例:

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

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

不幸的是,如果我将通过WebStorm进行一些重构并将类bar中的属性baz重命名为Store,则函数fooBarLens将停止工作。 / p>

但是如果在重构之前,我将像这样重写函数fooBarLens

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

然后重构将正常工作。

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

1 个答案:

答案 0 :(得分: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']版本上的语法糖。重构工具有一天可能会赶上这种理解,如果他们还没有这样做的话。