Skip to content

signal forms: keyInParent() returns a string for array items (typed as number) #71616

Open

Description

@fabioemoutinho

Which @angular/* package(s) are the source of the bug?

forms

Is this a regression?

No

Description

In signal forms, the type of FieldState.keyInParent() doesn't match what it returns at runtime for array items.

It is declared as Signal<TKey>, where TKey is number for children of an array field, and the JSDoc says:

If the parent field is array-valued, for example, this is the index of this field in that array.

At runtime it returns a string:

const f = form(signal({items: [{n: 'a'}, {n: 'b'}]}));

f.items[1]().keyInParent(); // '1' (string); the type says number

Because the type says number, code like this compiles but never matches:

items.filter((_, i) => i !== item().keyInParent());

The string seems to come from how keys are produced rather than from a deliberate choice: the parent's children map is built from Object.keys(value) (packages/forms/signals/src/field/structure.ts, computeChildrenMap), and the field proxy's get trap receives '1' for f.items[1], so the key is a JS property-key string. FieldNode.keyInParent passes that string through as-is. (FieldContext.index already converts the same key with Number(key).)

Two ways to resolve it:

  1. Return a number for children of array fields, which matches the declared type and the JSDoc.
  2. Keep the string and change the type (and JSDoc) to string.

I'll open a PR for option 1, since it follows the existing type and docs, but either option removes the mismatch.

This was also noticed in passing in a comment on #67241.

Please provide a link to a minimal reproduction of the bug

Inline above. As a test:

it('keyInParent is a number for array items', () => {
  const f = TestBed.runInInjectionContext(() =>
    form(signal({items: [{n: 'a'}, {n: 'b'}]})),
  );
  expect(f.items[1]().keyInParent()).toBe(1); // fails: received '1'
});

Please provide the exception or error you saw

Expected '1' to be 1.

Please provide the environment you discovered this bug in (run ng version)

@angular/forms 22.2.3
Also reproduced on main (5244ea781d).

Anything else?

No response

Activity

  1. added this to the needsTriage milestone on Oct 26, 2026
  2. added this to the needsTriage milestone on Oct 26, 2026
  3. fabioemoutinho commented on Oct 26, 2026

    @fabioemoutinho
    ContributorAuthor

    Related: a fix for the same mismatch exists as an unmerged commit, bb6d010 (for #67241). See the discussion on #71617.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions