microsoft / microsoft/TypeScript

Spread operator in JSX causes loss of type information for inline functions defined outside the spread operator

Abierto
#54,841 3 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Bug Domain: JSX/TSX Help Wanted
Lenguaje dominante
Go
Estrellas
111k
Forks
14.4k
Merge medio
1 d 19 h
PR fusionados (30 d)
117

Descripción

Bug Report

When defining conditional types on a JSX component, using a spread operator causes loss of type information on inline functions while removing the spread operator resolves the issue.

🔎 Search Terms
  • "jsx spread"
  • "TS7006"
⏯ Playground Link

Playground link with relevant code

💻 Code

Given the following types and JSX:

/**
 * Either all properties are included, or none of them should be
 * @example
 * type Ex = AllOrNone<{ search: string; onSearchChange: (value: string) => void}>
 *
 * // Ok
 * const t1: Ex = {
 *   search: "hello",
 *   onSearchChange: (value) => console.log(value)
 * }
 *
 * // Error, needs onSearchChange
 * const t2: Ex = {
 *   search: "hello",
 * }
 *
 * // Error, needs search
 * const t3: Ex = {
 *   onSearchChange: (value) => console.log(value)
 * }
 */
export type AllOrNone<T> = T | { [K in keyof T]?: never };


export type OrderHistoryTableProps = {
  data: OrderRow[];
  noDataText?: string;
} & SortParams &
  FilterParams &
  SearchParams;

type SortParams = AllOrNone<{
  sorting: SortingState;
  onSortChange: (state: SortingState) => void;
}>;

type FilterParams = AllOrNone<{
  filter: ColumnFiltersState;
  onFilterChange: (state: ColumnFiltersState) => void;
}>;

type SearchParams = AllOrNone<{
  search: string;
  onSearchChange: (value: string) => void;
}>;

function OrderHistoryTable({
  data,
  noDataText = "No orders to display!",
  onFilterChange,
  onSortChange,
  sorting,
  filter,
  search,
  onSearchChange,
}: OrderHistoryTableProps): JSX.Element {
  ...
}

/* sorting, filter, and search are correct types */
<OrderHistoryTable
  data={rowData}
  {...{ sorting, filter, search }}
  onSortChange={onSortChange}
  onFilterChange={setFilter}
  onSearchChange={(value) => setSearch(value)} // TS7006: Parameter 'value' implicitly has an 'any' type.
/>

However, removing the spread operator resolves the issue:

<OrderHistoryTable
  data={rowData}
  sorting={sorting}
  filter={filter}
  search={search}
  onSortChange={onSortChange}
  onFilterChange={setFilter}
  onSearchChange={(value) => setSearch(value)}
/>
🙁 Actual behavior

While using the spread operator for other props, the inline function loses type information.

🙂 Expected behavior

Given that the values provided in the spread operator are the correct type, the arguments in the inline function should retain type information.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con la reproducción vinculada en CodeSandbox y el ejemplo de JSX, centrándote en el tipado contextual de la función onSearchChange inline cuando otras props utilizan un spread operator. Compara la comprobación de tipos con y sin el spread y, después, añade una prueba de regresión que muestre que el parámetro del callback conserva su tipo esperado.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
compilers
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
42/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.