nodejs / nodejs/node

`FormData` implementation/types mismatch

Open
#58,481 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
122k
Forks
37.3k
Avg merge
4d 2h
Merged PRs (30d)
283

Description

Version

v22.6.0

Platform
Darwin esmbp2023 23.5.0 Darwin Kernel Version 23.5.0: Wed May  1 20:17:33 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6031 arm64
Subsystem

Fetch

What steps will reproduce the bug?

Regarding FormData type definition (https://github.com/nodejs/node/blob/main/deps/undici/src/types/formdata.d.ts):

The majority of methods are defined as instance methods (e.g., append, set, getAll, etc.):

// EXAMPLE
export declare class FormData {
  // ...
  append (name: string, value: unknown, fileName?: string): void
  // ...
}

But the following methods are defined as properties:

  • forEach
  • keys
  • values
  • entries
  • Symbol.iterator
// EXAMPLE
export declare class FormData {
  // ...
  forEach: (
    callbackfn: (value: FormDataEntryValue, key: string, iterable: FormData) => void,
    thisArg?: unknown
  ) => void
  // ...
}

This prevents extending those methods when extending FormData:

// EXAMPLE
class StrictFormData<T> extends FormData {
    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/entries) */
    entries = <TK extends keyof T & string>(): IterableIterator<
        [TK, T[TK]]
    > => {
        // ERROR: TS2855: Class field entries defined by the parent class is not accessible in the child class via super.
        return super.entries() as IterableIterator<[TK, T[TK]]>;
    };
}
// EXAMPLE
class StrictFormData<T> extends FormData {
    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/entries) */
    // ERROR: TS2425: Class FormData defines instance member property entries, but extended class StrictFormData<T> defines it as instance member function.
    entries<TK extends keyof T & string>(): IterableIterator<[TK, T[TK]]> {
        // ERROR: TS2855: Class field entries defined by the parent class is not accessible in the child class via super.
        return super.entries() as IterableIterator<[TK, T[TK]]>;
    }
}

Is it a mistake in the type definitions?

When looking at the implementation (https://github.com/nodejs/node/blob/main/deps/undici/src/lib/web/fetch/formdata.js) I don't see any of those methods added, neither "statically", nor dynamically upon construction. I might be missing something because exactly those atypically defined methods are the ones that I cannot find in the implementation.

Thanks!

How often does it reproduce? Is there a required condition?

See above.

What is the expected behavior? Why is that the expected behavior?

See above.

What do you see instead?

See above.

Additional information

See above.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Compare deps/undici/src/types/formdata.d.ts with deps/undici/src/lib/web/fetch/formdata.js, focusing on forEach, keys, values, entries, and Symbol.iterator. Reproduce the TypeScript subclassing errors from the issue and determine whether the declarations or implementation differ from the intended behavior. Done means the FormData types and runtime behavior are consistent and the reported extension case is addressed.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nodejs, typescript
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.