jamesmcnamara / shades

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

Typescript mod functions don't allow type changes #20

Closed spiffytech closed 5 years ago

spiffytech commented 5 years ago

Given this code:

shades.mod('prop')((prop: number) => prop.toFixed())

I get a type error saying Type 'string' is not assignable to type 'number', meaning the typings don't allow me to change the type of the property.

jamesmcnamara commented 5 years ago

You are completely correct.

The first versions of the typings allowed for type changes, but in practice this actually led to lots of bugs slipping through the cracks. When I removed this feature, it caught a ton of errors, but there were also basically no cases where I WAS transforming the type.

However, in the very few cases where I do some sort of type conversion, I have just preferred to use intersection types:

interface Obj {
  prop: string | number;
}

declare const obj: Obj;

shades.mod('prop')(prop => prop.toFixed())(obj)

If you really need to refine the type to a before and after type, you can use a type guard:

interface Obj {
  prop: string | number;
}

interface CleanedObj {
  prop: string;
}

function isCleanedObj(obj: Obj): obj is CleanedObj {
  return typeof obj.prop === 'string';
}

TL;DR: You're 100% right. This is a self-imposed limitation to try and catch more bugs.