Skip to content

Inference is not working properlyΒ #63348

Description

πŸ”Ž Search Terms

inference
performance

⏯ Playground Link

link

πŸ™ Actual behavior

im testing some hard inference, and seems to be that typescript is not able to infer properly the generic type from the function parameter, so i have to specify it to make it able to works

for example

const [schema3, setSchema3] = useStoreByPath<{ schema: { subValue: number }; style: string }, 'schema.subValue'>('schema.subValue');

πŸ™‚ Expected behavior

if i specify the first argument of my function, this should automatically infer it

for example

const [schema3, setSchema3] = useStoreByPath<{ schema: { subValue: number }; style: string }>('schema.subValue');

i have attached a link where can be reproduced

Additional information about the issue

seems to be that the issue is when the first generic type is specified and we expect that the second argument will be inferred from the function parameters

Activity

  1. RyanCavanaugh commented on Apr 3, 2026

    @RyanCavanaugh
    Member

    seems to be that the issue is when the first generic type is specified and we expect that the second argument will be inferred from the function parameters

    This expectation is not correct. If a type argument is given, the rest of the parameter go to their defaults, not inference. See https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-parameter-defaults

  2. eduardocque commented on Apr 3, 2026

    @eduardocque
    Author

    Ryan Cavanaugh (@RyanCavanaugh) thanks for your time, is there a way to make this works ? or do i need to re-think my whole solution ?

    or can be posible to make a proposal ? in that way we can avoid be duplicating the value of the generic and in the argument of the function twice like u can see in my example instead go automatically to the default value

  3. RyanCavanaugh commented on Apr 3, 2026

    @RyanCavanaugh
    Member

    Suggestion is tracked at #26242 btw.

    I don't have a good sense of what your intended API design is here. Like where is style coming from?

  4. eduardocque commented on Apr 3, 2026

    @eduardocque
    Author

    Ryan Cavanaugh (@RyanCavanaugh) im trying to make a global store, where the first argument is the state type { schema: { subValue: number }; style: string } and the second generic is the path based on dots, for example schema.subValue so the function will give me that value.

    in the function parameters TS should predict all of the possible paths ['schema', 'schema.subValue', 'style',....], so i have to specify it

    of course the function is dynamic based on the state that needs to manage, thats why was expecting to specify the first generic and leave the second to be infered based on the first parameter in the function path

    if is required i can give you the full code

    Note,

    due this limitation i have tu put twice the generic and the function parameter value, for example

    
    // type function
    
    function useStoreByPath<TState extends object, P extends PathOf<TState>>(
      path: P,
      equalityFn?: (a: PathValue<TState, P>, b: PathValue<TState, P>) => boolean
    ): [
      PathValue<TState, P>,
      (value: PathValue<TState, P> | ((prev: PathValue<TState, P>) => PathValue<TState, P>)) => void
    ];
    
    // example
    
    const [subValue, setSubValue] = useStoreByPath<{ schema: { subValue: number }; style: string }, 'schema.subValue'>('schema.subValue');
    

    due that the second generic is not infered, if i dont put it, TS complains Expected 2 type arguments, but got 1.

  5. RyanCavanaugh commented on Apr 3, 2026

    @RyanCavanaugh
    Member

    The standard workaround is to use a curried function:

     function useStoreByPath<TState extends object>() {
       return <P extends PathOf<TState>>(
         path: P,
         equalityFn?: (a: PathValue<TState, P>, b: PathValue<TState, P>) => boolean
       ): [PathValue<TState, P>, (value: PathValue<TState, P> | ((prev: PathValue<TState, P>) => PathValue<TState, P>)) => void] => {
         // implementation
       };
     }
     
     // Usage: specify TState manually, P is inferred
     const [subValue, setSubValue] = useStoreByPath<{ schema: { subValue: number }; style: string }>()('schema.subValue');
  6. eduardocque commented on Apr 3, 2026

    @eduardocque
    Author

    for a library perspective wont looks good :/, can be possible to request a change request or suggestion ? or could break how typescript manage the generics ?

    just in case, thanks for the help if is not possible will try to find another way

  7. MartinJohns commented on Apr 3, 2026

    @MartinJohns
    Contributor

    can be possible to request a change request or suggestion ?

    He already linked the relevant existing issue: #26242

  8. typescript-bot commented on Apr 6, 2026

    @typescript-bot
    Contributor

    This issue has been marked as "Working as Intended" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

  9. eduardocque commented on Apr 6, 2026

    @eduardocque
    Author

    Ryan Cavanaugh (@RyanCavanaugh) hi, a question if is working as expected, instead reopen this one, should i wait for #26242 ?

    Regards

  10. locked as resolved and limited conversation to collaborators on Jun 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions