joshhunt
joshhunt

Reputation: 5335

Typescript: How to type rest object destructure

If I have these two objects

interface Input {
    one?: string;
    two?: string;
    c?: string
}

interface Data {
    one?: string;
    a?: string;
    b?: string;
    c?: string
}

currently I have to do something like

const { one, two, ...restOfData } = input;
const data: Data = {...restOfData};

Is it possible to type ...restOfData directly?

I would like to be able to do this

const { one, two, ...data } = input;
data.one = 'test' + one;
data.a = one;

Upvotes: 14

Views: 10633

Answers (1)

artem
artem

Reputation: 51589

You can type the destructure as intersection of Input and a type which has all fields from Data but optional. For that "optional Data" type, you can use built-in Partial type:

const { one, two, ...data }: Input & Partial<Data> = input; 
// data type is  inferred as data: { c: string; a?: string; b?: string; }
// so you now can
data.a = one;

If you want some properties to remain in the data object, I can't think of anything better than doing two destructuring, one without "rest" object, and the second one with it. If you want one to remain in data, but remove two, you can do this

interface Input {
    one?: string;
    two?: string;
    c?: string
}

interface Data {
    one?: string;
    a?: string;
    b?: string;
    c?: string
}
let input: Input;

const { one } = input;
const { two, ...data }: Input & Data = input;

data.one = 'test' + one;
data.a = one;

If you want all properties to remain, you can have data as shallow copy of input like this

const { one, two } = input;
const { ...data }: Input & Data = input;

Upvotes: 13

Related Questions