如何将readonly方法附加到来自redux的对象?

时间:2019-12-25 01:07:06

标签: javascript typescript redux

说我要在redux中存储一个带有名字和姓氏字段的“用户”对象(如果使用打字稿,则为interface User { firstName : string, lastName : string})。从redux检索用户后,说我想获得用户的全名,计算方式为${user.firstName} ${user.lastName}。现在,我有一个功能:

function getFullName(user: User) : string { 
  return `${user.firstName} ${user.lastName}`
}

但是,在我的实际应用程序中,我有很多这样的只读函数,并且确实希望有一种方法,我可以将其称为user.getFullName()甚至是user.fullName。这样,我就不必记住导入每个函数,也不必记住哪些东西是属性,哪些是函数,等等。

我想可以做到这一点,只要在从redux得到任何东西时就实例化分类对象,并记得在保存到redux以转换为普通的js-object时记得做{...user}。但是,这将为redux添加更多样板,尤其是使用打字稿时。

这似乎应该是一个已解决的问题,是否有一个简单,简化的解决方案?

1 个答案:

答案 0 :(得分:0)

JS对象中的成员函数与其他属性相同。因此,您可以在getFullName()接口上定义成员函数User并在initalUserState中对其进行定义。 getFullName()将在执行还原操作后保留。

interface User {
    firstName: string; lastName: string;
    getFullName: () => string;
}

const initalUserState: User = {
    firstName: '',
    lastName: '',
    getFullName () {
        return `${this.firstName} ${this.lastName}`;
    },
}

const reducer: Reducer<User, Action> = (state = initalUserState, action): User => {
    // action processing logic
    return state;
}

传播语法{ ...state, firstName: action.firstName }仍然有效,并且不会覆盖getFullName()方法。

在组件中,您可以像下面一样使用getFullName()

const Cmp1: FC<User> = (user) => <div>{user.getFullName()}</div>

export default connect<User, {}, {}, ApplicationState>
    (state => state.user, null)(Cmp1)