Why does using spread synax(...) not honor type-safety for an expected return type in typescript

204 Views Asked by At

I've got a function which is expected to return an object with specific keys. In my case, I only want to add the keys conditionally, so I am using spread syntax to help with that.

However, when I use spread syntax, I can add any old key to the object. I would expect the TS compiler to be able to tell that this will add a property that shouldn't be allowed.

Is this a misunderstanding on my part of how things should work? A bug in TS compiler? A mistake in my code?

Removing the spread syntax around the wut property brings back the red squigglies I would expect to have there.

TS-playground link

type Value = 'foo'| 'bar'| 'baz';

const getValues = (): Partial<Record<Value, string>> => {
    return {
        foo: 'someFoo',
        baz: 'someBaz',
        ...({wut: 'somewut'})
    }
}
1

There are 1 best solutions below

3
ThePuzzleMaster On

Thanks all for the helpful comments, and apologies for the terminology mixup on my part re: destructuring/spread.

It looks like my options are to either forgo the type-safety and leave my code how it is, or add my properties directly within if statements to gate behind some conditional logic if I want to keep the type safety.

type Value = 'foo'| 'bar'| 'baz';

const getValues = (): Partial<Record<Value, string>> => {
    const result: Partial<Record<Value, string>> = {}
    if (true) { // assume something meaningful within the if()
        result.foo = 'someFoo'
    }
    if (true) { // assume something meaningful within the if()
        result.bar = 'someFoo'
    }
    
    return result;
}