Skip to content

Codegen refuses Record<string, T> in a TypeScript TurboModule spec: Unrecognized generic type 'Record' #59981

Open

Description

@YevheniiKotyrlo

Description

@react-native/codegen's TypeScript parser refuses Record<string, T> in a NativeModule spec, and Readonly<Record<string, T>> the same way, with Unrecognized generic type 'Record' in NativeModule spec., while it reads {[key: string]: T}, the type Record<string, T> names, as a dictionary of T.

On main (de7e643) the refusal is the default branch of translateTypeReferenceAnnotation, since emitCommonTypes' table has no Record; a type literal with an index signature goes to emitDictionary.

Expected: Record<string, T> and Readonly<Record<string, T>> parse as {[key: string]: T} does, to a GenericObjectTypeAnnotation whose dictionaryValueType is T, and {[key: string]: T} and CodegenTypes.UnsafeObject keep the schema they get today.

Steps to reproduce

  1. Clone the reproducer below. ReproducerApp/specs/NativeSample.ts is a TurboModule spec with one method, setOptions(options: Record<string, unknown>): void.
  2. Run its repro.sh in a node:24 container:
    docker run --rm -v "$PWD:/repro:ro" node:24 bash /repro/repro.sh
    It installs react-native@nightly and parses the spec with @react-native/codegen/lib/cli/combine/combine-js-to-schema-cli.js, the script Android's generateCodegenSchemaFromJavaScript task runs, beside copies of the spec whose parameter is Readonly<Record<string, unknown>>, {[key: string]: unknown} and CodegenTypes.UnsafeObject.
  3. Expected: both Record spellings parse to the schema {[key: string]: unknown} gets. Actual: codegen refuses both:
    Record<string, unknown> -> UnsupportedGenericParserError: Module NativeSample: Unrecognized generic type 'Record' in NativeModule spec.
    Readonly<Record<string, unknown>> -> UnsupportedGenericParserError: Module NativeSample: Unrecognized generic type 'Record' in NativeModule spec.
    
    bash /repro/repro.sh 0.88.1 shows the same on the latest stable.

React Native Version

0.88.1

Affected Platforms

Build - Linux

Areas

TurboModule - The New Native Module System, Codegen

Output of npx @react-native-community/cli info

System:
  OS: Linux 6.18 Debian GNU/Linux 12 (bookworm) 12 (bookworm)
  CPU: (24) x64 AMD Ryzen 9 9950X3D 16-Core Processor
  Memory: 120.26 GB / 125.63 GB
  Shell:
    version: 5.2.15
    path: /bin/bash
Binaries:
  Node:
    version: 24.22.2
    path: /usr/local/bin/node
  Yarn:
    version: 1.22.22
    path: /usr/local/bin/yarn
  npm:
    version: 11.19.1
    path: /usr/local/bin/npm
  Watchman: Not Found
SDKs:
  Android SDK: Not Found
IDEs:
  Android Studio: Not Found
Languages:
  Java: Not Found
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli": Not Found
  react: Not Found
  react-native:
    installed: 0.90.0-nightly-20261112-897cca827
    wanted: ^0.90.0-nightly-20261112-897cca827
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

Stacktrace or Logs

== install react-native@nightly
react-native 0.90.0-nightly-20261112-897cca827 with @react-native/codegen 0.90.0-nightly-20261112-897cca827
== parse each spelling of the parameter with node_modules/@react-native/codegen/lib/cli/combine/combine-js-to-schema-cli.js
Record<string, unknown> -> UnsupportedGenericParserError: Module NativeSample: Unrecognized generic type 'Record' in NativeModule spec.
Readonly<Record<string, unknown>> -> UnsupportedGenericParserError: Module NativeSample: Unrecognized generic type 'Record' in NativeModule spec.
{[key: string]: unknown} -> {"type":"GenericObjectTypeAnnotation","dictionaryValueType":{"type":"GenericObjectTypeAnnotation"}}
CodegenTypes.UnsafeObject -> {"type":"GenericObjectTypeAnnotation"}
SUMMARY: react-native 0.90.0-nightly-20261112-897cca827's codegen does not read Record<string, unknown> as it reads {[key: string]: unknown}

MANDATORY Reproducer

https://github.com/YevheniiKotyrlo/react-native-codegen-record-in-module-spec

Screenshots and Videos

No response

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions