5

I have two interfaces. They are really similar except for one key.

interface InitialStateFromDB {
  uploads: {
    companyImage: string,
    map: string
  },
  adminPasswords: string,
  postInfos: PostInfo[] | undefined
}

interface InitialState extends Omit<InitialStateFromDB, 'adminPasswords'> {
  adminPasswords: AdminPassword
}

And I get initialState from DB.

const initialStateFromDB: InitialStateFromDB = window.__PRELOADED_STATE__;

Then I extract value of each property from initialStateFromDB to make initialState.

let adminPasswords: AdminPassword = JSON.parse(initialStateFromDB.adminPasswords);
const initialState : InitialState = {
  uploads : initialStateFromDB.uploads,
  adminPasswords,
  postInfos: initialStateFromDB.postInfos
}

But I think there is a more simple way to merge except adminPasswords property. So I searched about this.

Clone a js object except for one key

But, I don't know how to do like that in typescript.

So, My question is that "How to clone object except for one key in Typescript"

Byeongin Yoon
  • 1,735
  • 2
  • 17
  • 30

2 Answers2

5

What you need is spread operator (check the "Object Spread and Rest" part). Typescript is a superset of JavaScript, both of them support this feature.

const {adminPasswords, ...state} = initialStateFromDB;
const initialState: InitialState = {
  ...state,
  adminPasswords: JSON.parse(adminPasswords)
}
Xie Guanglei
  • 328
  • 1
  • 6
  • 2
    this actually doesn't work if you want to omit the key completely, only works if you override it with something else. I haven't managed to do this in an elegant manner without casting. {...state, adminPasswords: undefined } does not match Omit – Hoffmann Sep 23 '19 at 08:35
  • Note that this creates a shallow clone, not a deep clone. – Atte Juvonen Jan 12 '21 at 17:48
0

I found one option that works if you want to omit the key entirely instead of overriding it - using ts object rest (ref documentation here):

In the case of the question asked, it'd be:

const {adminPasswords, ...initialState} : InitialState = {...initialStateFromDB};

The line above makes a copy of 'initialStateFromDB' excluding the 'adminPasswords' field. The new object created is 'initialState'.