Search code examples
typescripttype-safety

How to type-safely remove a property from a TypeScript type


Let's have the following two interfaces:

interface A {
  foo: string;
  bar: number;
}

interface B {
  foo: string;
}

How can I type-safely convert an object that conforms to A to one that conforms to B?

This doesn't work:

const a = { foo: "baz", bar: 42 }
const b: B = {...a}
delete b.bar           // <=== cannot remove "bar" because B has no "bar"

I could do it without type-safety:

const a = { foo: "baz", bar: 42 }
const temp: any = {...a}
delete temp.bar
const b: B = temp

I assume this works:

const a = { foo: "baz", bar: 42 }
const b: B = {
  ...a,
  bar: undefined
}

But this is not what I want, as it assigns undefined to b.bar, which could lead to problems (e.g. Firestore won't accept it as input, as it does not allow undefined values).

Is there a type-safe way to do this?


Solution

  • One thing that you can do is destructuring assigment. Something similar to this:

    const a = { foo: "baz", bar: 42 }
    const {foo, ...b}= a
    

    b with contain all properties except foo. TS will be able to use infer the type for b as being compatible with B.