Skip to content

feat(types): improve isArray option type inference#804

Open
abhu85 wants to merge 1 commit intoNaturalIntelligence:masterfrom
abhu85:feat/isarray-type-inference
Open

feat(types): improve isArray option type inference#804
abhu85 wants to merge 1 commit intoNaturalIntelligence:masterfrom
abhu85:feat/isarray-type-inference

Conversation

@abhu85
Copy link

@abhu85 abhu85 commented Mar 18, 2026

Summary

This PR improves the TypeScript type definitions for the isArray option and other callbacks that receive jPath or Matcher parameters, addressing the concerns raised in #803.

The Problem

The current type definition uses string | Matcher (where Matcher = unknown) for callbacks like isArray, tagValueProcessor, etc. This forces users to use type assertions even when they know jPath: true (the default):

// Current behavior - TypeScript error!
const options: X2jOptions = {
  isArray: (_tagName, jPath, _isLeafNode, _isAttribute) => {
    // Error: Argument of type 'string | unknown' is not assignable to parameter of type 'string'
    return ['root.items'].includes(jPath);
  }
};

The Solution

This PR introduces discriminated union types based on the jPath option:

// Now works without type assertions!
const options: X2jOptions = {
  // jPath defaults to true, so jPath is inferred as string
  isArray: (_tagName, jPath, _isLeafNode, _isAttribute) => {
    return ['root.items'].includes(jPath); // jPath is string
  }
};

// Explicit jPath: true
const optionsWithString: X2jOptions = {
  jPath: true,
  isArray: (_tagName, jPath, _isLeafNode, _isAttribute) => {
    return jPath.startsWith('root.'); // jPath is string
  }
};

// Explicit jPath: false
const optionsWithMatcher: X2jOptions = {
  jPath: false,
  isArray: (_tagName, matcher, _isLeafNode, _isAttribute) => {
    // matcher is Matcher (unknown) - users must handle appropriately
    return false;
  }
};

New Exported Types

  • X2jOptionsBase: Base options shared by both jPath modes
  • X2jOptionsWithJPathString: Options when jPath: true (callbacks receive string)
  • X2jOptionsWithMatcher: Options when jPath: false (callbacks receive Matcher)
  • X2jOptions: Union of the above two types

Affected Callbacks

All callbacks that previously used string | Matcher now properly narrow based on jPath:

  • isArray
  • tagValueProcessor
  • attributeValueProcessor
  • updateTag
  • ignoreAttributes (function form)

Test Plan

  • TypeScript compilation passes for the type definition file
  • Added type test files demonstrating correct type inference
  • Added type error test files verifying TypeScript catches incorrect usage
  • Existing test suite passes (307 specs, 1 unrelated failure)

Fixes #803

Add discriminated union types for X2jOptions based on the jPath option.
When jPath is true (default), callbacks like isArray, tagValueProcessor,
attributeValueProcessor, etc. receive jPath as a string. When jPath is
false, callbacks receive a Matcher instance.

This allows TypeScript to properly narrow the type of the callback
parameter based on the jPath option value, eliminating the need for
type assertions when using string methods on jPath.

Exports new types:
- X2jOptionsBase: Base options shared by both modes
- X2jOptionsWithJPathString: Options for jPath: true (string callbacks)
- X2jOptionsWithMatcher: Options for jPath: false (Matcher callbacks)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enhance type definition for XMLParser isArray option when using TypeScript

1 participant