Skip to content

Generic return type only partially respected #40307

Closed
@ivoiv

Description

@ivoiv

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.

Playground Link:
https://www.typescriptlang.org/play?ts=4.1.0-dev.20200828#code/GYVwdgxgLglg9mABAZygQygUwMICdMZy4A8AKgDSIDSimAHlmACbKIBKmERTxaYAnpVIA+YQApUGTAC5EFRPiYgImXLInoss0gEpEAXmHU9Ab0QBfAFCXJWPAShExZtLICMFyrcwGjzxAgyiGYAdGHelABGsgBMFhY6OkA

Related Issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already createdFix AvailableA PR has been opened for this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions