Description
TypeScript Version: 4.0.2 / 4.1.0-dev.20200828
Search Terms: generic return type not respected
This is a rather nonsensical reducer factory, taking a State and a Function as parameters.
The Function takes an argument which is the same type as the State and returns an object where keys can be any record type, and their values are basically copies of State.
I feel like I might be doing something wrong but I can't find any answer either in the FAQ or on StackOverflow.
Code
This does NOT throw an error, but it should:
function reducerFactory<
T,
K extends Record<any, T>
>(state: T, reducer: (state: T) => K) {}
reducerFactory({ a: 1 }, (state) => ({
one: { ...state, b: 2 } // should throw error, but works fine
}));
This correctly throws an error
function reducerFactory<
T,
K extends Record<any, T>
>(state: T, reducer: (state: T) => K) {}
reducerFactory({ a: 1 }, (state) => ({
one: { b: 2 } // Type '{ b: number; }' is not assignable to type '{ a: number; }'.
}));
This correctly throws an error
function reducerFactory<
T,
K extends Record<any, T>
>(state: T, reducer: (state: T) => K) {}
reducerFactory({ a: 1 }, (state) => ({
one: { a: 'foo', b: 2 } // Type 'string' is not assignable to type 'number'.
}));
EDIT: I thought K extends Record was maybe somehow too vague so I made the return type a bit more explicit but still the same issue.
function reducerFactory<T>(
state: T,
reducer: (state: T) => { [key: string]: T }
) {}
reducerFactory({ a: 1 }, (state) => ({
one: { ...state, b: 2 }, // should throw error but works fine
}));
Expected behavior:
Type '{ a: number, b: number; }' is not assignable to type '{ a: number; }'.
Object literal may only specify known properties, and 'b' does not exist in type '{ a: number; }'.
Actual behavior:
Code compiles without errors.
Related Issues: