jamesmcnamara / shades

A lodash-inspired lens-like library for Javascript
MIT License
412 stars 14 forks source link

updateAll not working well in a case #39

Closed jethrolarson closed 2 years ago

jethrolarson commented 4 years ago

TS 3.8.2 strict

type A = {f: boolean; g: number};
const a: A = {f: false, g: 1};
updateAll<A>(set('f')(true), set('g')(2))(a);

produces

Argument of type '<S extends HasKey<"f", true>>(s: S) => S' is not assignable to parameter of type '(state: A) => A'.
  Types of parameters 's' and 'state' are incompatible.
    Type 'A' is not assignable to type 'HasKey<"f", true>'.
      Type 'A' is not assignable to type '{ f?: true | undefined; }'.
        Types of property 'f' are incompatible.
          Type 'boolean' is not assignable to type 'true | undefined'.ts(2345)
jethrolarson commented 4 years ago

I found a sucky work-around of

updateAll<A>(set('f')<boolean>(true), set('g')(2))(a);
jamesmcnamara commented 4 years ago

Yeah for some reason booleans always trigger this weird behavior. I will try to do some investigation.

jethrolarson commented 4 years ago

It's probably just that the setter is specifying the type of the object and infers the smallest type. I don't know how to solve that and keep the same api though.

It's odd that

set('f')(true)(a)

works though

jethrolarson commented 4 years ago

same problem occurs with fill

updateAll<A>(fill({f: true}), set('g')(2))(a);
jamesmcnamara commented 4 years ago

Very strange. Soon I should get a weekend off and I'll take a peek at this (and other outstanding issues)

jamesmcnamara commented 2 years ago

This is resolved by newer versions of TypeScript. I'll publish shades@2.2.0 later today which upgrades all dependencies.