Skip to content

JSX with generics loses type inference on children if its a callback #2802

@Gabrola

Description

@Gabrola

Steps to reproduce

import React from 'react';

declare const TestComponentWithChildren: <T, TParam>(props: {
  state: T;
  selector?: (state: NoInfer<T>) => TParam;
  children?: (state: NoInfer<TParam>) => React.ReactNode | undefined;
}) => React.ReactNode;

declare const TestComponentWithoutChildren: <T, TParam>(props: {
  state: T;
  selector?: (state: NoInfer<T>) => TParam;
  notChildren?: (state: NoInfer<TParam>) => React.ReactNode | undefined;
}) => React.ReactNode;

const App = () => {
  return (
    <>
      <TestComponentWithChildren state={{ foo: 123 }} selector={(state) => state.foo}>
        {(selected) => <div>{Math.max(selected, 0)}</div>}
      </TestComponentWithChildren>

      <TestComponentWithoutChildren
        state={{ foo: 123 }}
        selector={(state) => state.foo}
        notChildren={(selected) => <div>{Math.max(selected, 0)}</div>}
      />
    </>
  );
};

Behavior with typescript@6.0

selected is inferred as a number in TestComponentWithChildren and type-checking succeeds

Behavior with tsgo

selected is resolved as unknown in TestComponentWithChildren and this code fails type-checking.

src/index.tsx:19:39 - error TS2345: Argument of type 'unknown' is not assignable to parameter of type 'number'.

19         {(selected) => <div>{Math.max(selected, 0)}</div>}
                                         ~~~~~~~~

Interestingly, this happens only with children in TestComponentWithChildren but not in notChildren in TestComponentWithoutChildren

Version Information

This behavior was introduced in 7.0.0-dev.20260213.1, this problem does not occur in 7.0.0-dev.20260212.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions