microsoft / microsoft/TypeScript

Disallow excess properties to React components (for performance)

Ouverte
#29,883 15 commentaires 44 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Needs Proposal Suggestion
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

Search Terms

react excess props properties component function parameters

Suggestion

import * as React from 'react';
import { ComponentType } from 'react';

type Props = { foo: 1 };
declare const MyComponent: ComponentType<Props>;
declare const propsWithExtras: Props & { bar: 1 };

// Expected error, but got none
<MyComponent {...propsWithExtras} />;

I understand this matches TypeScript's behaviour with functions:

type Props = { foo: 1 };
declare const MyFunction: (props: Props) => void;
declare const propsWithExtras: Props & { bar: 1 };

// No error
MyFunction(propsWithExtras);
MyFunction({ ...propsWithExtras });

However, with React, passing excess props to a component is a performance concern, since those excess props may break component memoization, causing the component to update more frequently than it should.

In my experience, this error most often occurs when wrapping components, where the wrapper components need to "pass through" types to a child:

type MyComponentProps = { foo: 1 };
declare const MyComponent: ComponentType<MyComponentProps>;

type MyWrapperComponent = MyComponentProps & { myWrapperProp: 1 };
const MyWrapperComponent: ComponentType<MyWrapperComponent> = props => (
    <MyComponent
        // We're passing too many props here, but no error!
        {...props}
    />
);

Workarounds I'm aware of: (1) avoid spreading, but this quickly becomes a non-option when a component has many props you have to manually pick and pass through.

const MyWrapperComponent: ComponentType<MyWrapperComponent> = ({ foo, myWrapperProp }) => (
    // Error as expected due to excess prop `myWrapperProp`
    <MyComponent foo={foo} myWrapperProp={myWrapperProp} />
);

(2) Pass through props via an object.

type MyWrapperComponent = { myComponentProps: MyComponentProps } & { myWrapperProp: 1 };
const MyWrapperComponent: ComponentType<MyWrapperComponent> = ({ myComponentProps, myWrapperProp }) => (
    // Error as expected due to excess prop `myWrapperProp`
    <MyComponent {...myComponentProps} myWrapperProp={myWrapperProp} />
);

However then we lose special JSX behaviour such as the ability to pass data attributes as props.

IIUC, this could be a use case for https://github.com/Microsoft/TypeScript/issues/12936.

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par reproduire les exemples TypeScript et JSX de l’issue, puis lisez la discussion associée sur les excess properties dans l’issue #12936. Le travail est terminé lorsque les props excédentaires fournies via un component spread produisent une erreur de type, tandis que le comportement existant des fonctions, les attributs de données JSX et la sortie JavaScript restent compatibles.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
react, typescript
Domaine
compilers, frontend
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
28/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.