-
Notifications
You must be signed in to change notification settings - Fork 511
Description
Various object functions in es-toolkit (and probably originally lodash DefinitelyTyped defs) are unsound. This may be intentional, but I don't see any documentation of whether it's intentional or not, or any general warnings about errors that could result, so I don't know if you've thought about it.
For example:
import { mapValues } from 'es-toolkit/object'
function unsound(obj: { a: number }) {
return mapValues(obj, (x) => x.toFixed(2)) // 💥 crashes on `b: true` property below
}
const x = { a: 1, b: true }
unsound(x) // No TS errors, but crashes 😬This is similar to how TS chose to make Object.keys() soundly return string[], but accidentally accepted a contradictory change that allows Object.values() to unsoundly return T[keyof T][] instead of unknown[]. There's a lot of debate over how the contradiction should be resolved.
If soundness is preferrable you could declare the getNewValue type as
getNewValue: (value: SoundValueOf<T>, key: string, object: T) => V
Where
type SoundValueOf<T> = string extends keyof T ? T[keyof T] : unknownThis would catch the issue above at compile time, and wouldn't cause any new errors for objects where the key type is any string (hopefully the most common case for iterating an object?) But it would cause new errors if the key type is narrower than string.
If the types are intended to be pragmatic then it wouldn't hurt to explain that there could be unexpected errors if an object has additional properties not anticipated by the type literal.