jamesmcnamara / shades

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

Type A not assignable to type B #46

Open virzen opened 4 years ago

virzen commented 4 years ago

Setting value of a field which is of type U to a value of type A, where A is a union case of U causes an error when A is refined.

Minimal example

import { set } from "shades";

type A = { type: "a" };
type B = { type: "b" };
type U = A | B;

type Test = {
  union: U;
};

const t: Test = { union: { type: "a" } };

console.log(t);

console.log(set("union")(({ type: "b" }) as B)(t)); // Type 'A' is not assignable to type 'B'

https://codesandbox.io/s/divine-frost-3xe5b?file=/src/index.ts:0-254

I think an issue might be in how HasKey is used in the type definition

export function set<K1 extends string>(k1: K1): <V>(v: V) => <S extends HasKey<K1, V>>(s: S) => S

Here the type S is defined to be something that has a key with value of type V, whereas I think it should be of some kind of supertype of V.

I've tried with

export function set<K1 extends string>(k1: K1): <V>(v: V) => <T extends V, S extends HasKey<K1, T>>(s: S) => S

but that removes error even for incorrect types.