Je ne peux pas comprendre comment définir les valeurs de propriété par défaut pour mes composants à l'aide de Typescript.
Voici le code source:
class PageState
{
}
export class PageProps
{
foo: string = "bar";
}
export class PageComponent extends React.Component<PageProps, PageState>
{
public render(): JSX.Element
{
return (
<span>Hello, world</span>
);
}
}
Et quand j'essaye d'utiliser le composant comme ceci:
ReactDOM.render(<PageComponent />, document.getElementById("page"));
J'obtiens une erreur indiquant que la propriété foo
est manquante. Je souhaite utiliser la valeur par défaut. J'ai également essayé d'utiliser static defaultProps = ...
à l'intérieur du composant, mais cela n'a eu aucun effet comme je le soupçonnais.
src/typescript/main.tsx(8,17): error TS2324: Property 'foo' is missing in type 'IntrinsicAttributes & IntrinsicClassAttributes<PageComponent> & PageProps & { children?: ReactEle...'.
Comment puis-je utiliser les valeurs de propriété par défaut? De nombreux composants JS que mon entreprise utilise en dépendent et ne pas les utiliser n'est pas un choix.
static defaultProps
est correct. Pouvez-vous publier ce code?Réponses:
Accessoires par défaut avec composant de classe
L'utilisation
static defaultProps
est correcte. Vous devriez également utiliser des interfaces, pas des classes, pour les accessoires et l'état.Mise à jour 2018/12/1 : TypeScript a amélioré la vérification de type liée au
defaultProps
fil du temps. Poursuivez votre lecture pour connaître les utilisations les plus récentes et les plus importantes jusqu'aux utilisations et problèmes plus anciens.Pour TypeScript 3.0 et plus
TypeScript a spécifiquement ajouté la prise en charge pour
defaultProps
que la vérification de type fonctionne comme vous le souhaitez. Exemple:Qui peut être rendu et compilé sans passer d'
foo
attribut:Notez que:
foo
n'est pas marqué comme facultatif (c'est-à-direfoo?: string
) même s'il n'est pas requis comme attribut JSX. Marquer comme facultatif signifierait que cela pourrait l'êtreundefined
, mais en fait, ce ne sera jamaisundefined
parce quedefaultProps
fournit une valeur par défaut. Pensez-y de la même manière que vous pouvez marquer un paramètre de fonction comme facultatif, ou avec une valeur par défaut, mais pas les deux, mais les deux signifient que l'appel n'a pas besoin de spécifier une valeur . TypeScript 3.0+ traitedefaultProps
de la même manière, ce qui est vraiment cool pour les utilisateurs de React!defaultProps
n'a pas d'annotation de type explicite. Son type est déduit et utilisé par le compilateur pour déterminer les attributs JSX requis. Vous pouvez utiliserdefaultProps: Pick<PageProps, "foo">
pour vous assurer quedefaultProps
correspond à un sous-ensemble dePageProps
. Plus d'informations sur cette mise en garde sont expliquées ici .@types/react
version16.4.11
pour fonctionner correctement.Pour TypeScript 2.1 jusqu'à 3.0
Avant que TypeScript 3.0 n'implémente la prise en charge du compilateur,
defaultProps
vous pouviez toujours l'utiliser, et cela fonctionnait à 100% avec React au moment de l'exécution, mais comme TypeScript ne considérait que les accessoires lors de la vérification des attributs JSX, vous deviez marquer les accessoires qui ont des valeurs par défaut comme facultatifs avec?
. Exemple:Notez que:
defaultProps
avecPartial<>
pour qu'il vérifie le type par rapport à vos accessoires, mais vous n'avez pas à fournir à chaque propriété requise une valeur par défaut, ce qui n'a aucun sens puisque les propriétés requises ne devraient jamais avoir besoin d'une valeur par défaut.strictNullChecks
la valeur dethis.props.foo
serapossibly undefined
et nécessitera une assertion non nulle (iethis.props.foo!
) ou un type-guard (ieif (this.props.foo) ...
) pour supprimerundefined
. C'est ennuyeux car la valeur de prop par défaut signifie qu'il ne sera jamais indéfini, mais TS n'a pas compris ce flux. C'est l'une des principales raisons pour lesquelles TS 3.0 a ajouté un support explicite pourdefaultProps
.Avant TypeScript 2.1
Cela fonctionne de la même manière mais vous n'avez pas de
Partial
types, alors omettez simplementPartial<>
et fournissez les valeurs par défaut pour tous les accessoires requis (même si ces valeurs par défaut ne seront jamais utilisées) ou omettez complètement l'annotation de type explicite.Accessoires par défaut avec composants fonctionnels
Vous pouvez également utiliser
defaultProps
des composants de fonction, mais vous devez taper votre fonction dans l' interfaceFunctionComponent
(StatelessComponent
dans la@types/react
version antérieure16.7.2
) afin que TypeScript sachedefaultProps
sur la fonction:Notez que vous ne devez utiliser
Partial<PageProps>
nulle part car ilFunctionComponent.defaultProps
est déjà spécifié comme partiel dans TS 2.1+.Une autre alternative intéressante (c'est ce que j'utilise) est de déstructurer vos
props
paramètres et d'attribuer directement les valeurs par défaut:Alors vous n'en avez pas du tout besoin
defaultProps
! Sachez que si vous ne fournissezdefaultProps
sur un composant de fonction , il aura la priorité sur les valeurs des paramètres par défaut, car React toujours passer explicitement lesdefaultProps
valeurs (si les paramètres ne sont jamais non défini, donc le paramètre par défaut est jamais utilisé.) Vous utiliseriez l'un ou l'autre, pas les deux.la source
<PageComponent>
quelque part sans passer l'foo
accessoire. Vous pouvez le rendre facultatif en utilisantfoo?: string
dans votre interface.public static defaultProps
oustatic defaultProps
(public
par défaut) pour que tout (compilateur et runtime React) fonctionne correctement. Cela peut fonctionner au moment de l'exécution avecprivate static defaultProps
uniquement parce queprivate
etpublic
n'existe pas au moment de l'exécution, mais le compilateur ne fonctionnerait pas correctement.Avec Typescript 2.1+, utilisez Partial <T> au lieu de rendre vos propriétés d'interface facultatives.
la source
Avec Typescript 3.0, il existe une nouvelle solution à ce problème:
Notez que pour que cela fonctionne, vous avez besoin d'une version plus récente de
@types/react
que16.4.6
. Cela fonctionne avec16.4.11
.la source
export interface Props { name?: string;}
où le nom est un accessoire optionnel ? Je continue de recevoirTS2532 Object is possibly 'undefined'
undefined
c'est une sorte de valeur par défaut automatique pour ces accessoires. Vous voulez pouvoir passer enundefined
tant que valeur explicite parfois, mais avez une autre valeur par défaut? Avez-vous essayé à laexport interface Props {name: string | undefined;}
place? Je n'ai pas essayé ça, juste une idée.?
est identique à l'ajout|undefined
. Je veux éventuellement passer dans l'accessoire, et laisserdefaultProps
gérer ce cas. On dirait que cela n'est pas encore possible dans TS3. Je vais simplement utiliser laname!
syntaxe redoutée car je sais que ce n'est jamaisundefined
quand ilsdefaultProps
sont définis. Merci quand même!Pour ceux qui ont des accessoires optionnels qui ont besoin de valeurs par défaut. Crédit ici :)
la source
D'après un commentaire de @pamelus sur la réponse acceptée:
En fait, vous pouvez utiliser l' héritage d'interface de Typescript . Le code qui en résulte n'est qu'un peu plus détaillé.
la source
Pour le composant fonctionnel, je préfère garder l'
props
argument, voici donc ma solution:la source
Composant fonctionnel
En fait, pour le composant fonctionnel, la meilleure pratique est comme ci-dessous, je crée un exemple de composant Spinner:
la source