TanStack / form

🤖 Powerful and type-safe form state management for the web. TS/JS, React Form, Solid Form, Lit Form and Vue Form.

Home Page:https://tanstack.com/form

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

DeepKeys produces keys incompatible with DeepValue

rodogir opened this issue · comments

Describe the bug

I noticed the bug when trying to use the Field component with a static name that points to a property inside of an array (e.g. friends.0.name). The useField hook and Field component will claim that the name prop is invalid, even though they function correctly. This is due how DeepKeys is defined. Further, I also noticed that DeepValue correctly handles array keys.

Your minimal, reproducible example

codesandbox

Steps to reproduce

DeepKeys problem

  1. Go to /src/example.spec.ts
  2. Look at the code and notice that type issues when trying to use DeepValue with DeepKeys

To see that Field works with array keys:

  1. Run the linked codesanbox
  2. You will see 2 input fields, change second one ("Robin") to whatever you want.
  3. Hit the submit button
  4. Check the console and verify that the values are as expected.
  5. The source code is under /src/App.tsx

Expected behavior

I expect DeepKeys to produce keys that are compatible with DeepValue. Also, I should be able to use Field with a key containing array indexes (e.g. friends.${number}.name).

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

It's a type issue and platform independent.

Tanstack Form adapter

None

TanStack Form version

0.13.3

TypeScript version

5.2.2

Additional context

No response

Technically you're not supposed to use DeepKeys and DeepValue outside of the internals of the library. They're exposed because they're how we build out the types and have to be to make the types "portable".

Also, the API you're trying to use with a number being part of the name isn't valid in framework adapters for this reason (IIRC). There's likely some work we need to do to clarify this (even probably changing the API).

Thanks for the clarification.

I'd like to provide some context for you to understand where we are coming from. We are building reusable, form-connected and type-safe input components. Here's an usage example:

function Example() {
  const form = useForm({
    defaultValues: {
      firstName: 'John',
      lastName: 'Doe',
      age: 42,
    }
  });

  return (
    <form>
      <FormTextField form={form} name="firstName" />
      <FormTextField form={form} name="lastName" />
      <FormNumberField form={form} name="age" />
    </form>
  );
}

We rely on DeepKeys and DeepValue to enforce type safety. For example, FormTextField accepts only names with string values, while FormNumberField is restricted to names with number values. This greatly improves our DX.

However, since DeepKeys and DeepValue are internal, I'm concerned about the sustainability of our approach. Are there alternative, officially supported methods for achieving similar levels of type safety with form components?

Agreed that this usage is the right way to go. It's how our docs will eventually encourage people to use TanStack Form.

Let's chat more in our Discord about how we can make this process easier and smoother for you (and others!). It might mean continuing to rely on DeepKeys and DeepValue for now but we introduce a more stable API in the future.

If nothing else, it'll help us shape what our docs should look like for this scenario.

This issue with the typings should not occur anymore. However, ignoring that, we'll be working on documenting in-house library usage prior to 1.x

Closing since we should discuss that in a different issue