In the following example im trying to figure out why my typing works for all parts of my object apart from my reducer return type?
If i explicitly set: reducer: (state, action): CounterState the compiler complains (as expected) that i'm not returning the right state. The thing is, i don't see why i should have to do this seeing as i'm already enforcing this within my Config type??
The simplified example:
interface CounterState {
counter: number;
}
type Reducer = () => CounterState
const reducer1: Reducer = () => ({
counter: 1,
foo: 'bar' // no errors, why?
})
const reducer2: Reducer = (): CounterState => ({
counter: 1,
foo: 'bar' // error: Object literal may only specify known properties
})
Finally I found the issue in GitHub, exactly about the problem. In short:
Ideally this would be an error. Unfortunately it turns out to be very difficult to fix this without possibly having consequences in terms of runaway recursion and/or performance
Original answer: Since typescript 1.6, object literals mustn't have extra properties. But if you cast an object to the type, extra properties are allowed. For example:
const state: CounterState = {
counter: 1,
foo: "bar" // Error, unknown property 'foo'
};
const state2 = {
counter: 1,
foo: "bar" // no errors
} as CounterState
It looks very similar to your problem, when you specify the lambda return type explicitly, the first rule is applied. But, if the return type isn't specified, the compiler thinks: "ok, may be I can cast the object to the CounterState... Is it ok? I'm not sure... But, I will try!", and the second rule is applied.
But I cannot refer to any documentation or compiler specification, which describes such behaviour, I didn't found it too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With