Skip to content

setPath: throws on missing optional path segments #554

Open

Description

@bombillazo

Hello, looking at the setPath logic, it seems to check if the path value on the object is not null/undefined before attempting to insert the new value. How can we set a new value to the object that is not yet defined?

Activity

  1. cjquines commented on Mar 2, 2024

    @cjquines
    Contributor

    the trouble with this is with undefined deeply nested paths:

    type T = Record<string, { a: number; b: number }>;
    const obj: T = {};
    
    R.setPath(obj, ["test", "a"], 2);

    there's no way to do this type-safely if obj.test isn't defined

  2. bombillazo commented on Mar 2, 2024

    @bombillazo
    Author

    Hey, yeah i figured if proper typing is a tenet of this library, it's gonna be hard to infer/produce a dynamic, nested property...

    It would be awesome, though. Not sure if one can create a dynamic type from a path, and make a union of the input param generic type with that dynamic type to type the output.

  3. Brodzko commented on Apr 1, 2024

    @Brodzko
    Contributor

    I stumbled upon a similar problem recently - I think it technically might even be possible to write a function like that type-safely(ish), but there might be too many decisions on how to handle edge-cases to have this on a library level.
    For example, what if the path contains an array index that is non-zero, but its parent property does not exist in target? Do you put the value at index 0 (thus not really upholding contract), or risk creating a sparse array?

    I'm not sure there are canonical answers to this and other edge-case questions, so it feels like something that should remain in user-land.

    I ended up ignoring array properties (didn't need them) and recursively creating a new object using objOf + some type magic to create a type from path in the end.

  4. changed the issue type fromtoon Jul 30, 2025
  5. eranhirsch commented on Jul 30, 2025

    @eranhirsch
    Member

    This is actually a bug! setPath can lead to an error being thrown, and the typing doesn't do enough to protect against it:

    setPath({} as Record<string, { b: number }>, ["a", "b"], 123);
  6. changed the title [-]`setPath` only works for existing properties[/-] [+]setPath: throws on missing optional path segments[/+] on Jul 30, 2025
  7. self-assigned this
    on Jul 30, 2025
  8. changed the title [-]setPath: throws on missing optional path segments[/-] [+]`setPath`: throws on missing optional path segments[/+] on Dec 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

runtimeIssues that refer to the runtime behaviortypingSomething type related

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions