web-dev-qa-db-fra.com

TypeScript avec des composants de style

Débutant TypeScript ici. J'ai un composant ci-dessous utilisant styled-components que je voudrais convertir en TypeScript.

import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'


const propTypes = {
  name: PropTypes.string.isRequired // https://material.io/tools/icons/?style=baseline
}

const Icon = styled(({name, className, ...props}) => <i className={`material-icons ${className}`} {...props}>{name}</i>)`
  font-size: ${props => props.theme.sizeLarger};
`

Icon.propTypes = propTypes

export default Icon

Je sais que je peux remplacer mon propTypes par un interface

interface Props {
  name: string
}

Cependant, TypeScript se plaint que je laisse className non déclaré. Le truc c'est que j'aimerais idéalement utiliser le interface comme une sorte de spécification pour les accessoires qu'un développeur peut fournir, sans avoir à déclarer des accessoires comme className ou theme qui sont injectés par des bibliothèques comme styled-components.

Comment convertir correctement ce composant en TypeScript?

7
artooras

Voici une approche complète utilisant Styled Components v5 avec React Native qui fonctionnera également avec plain React également. Si vous n'utilisez pas de thème, vous pouvez passer à la section StyledProps en bas.

  • Définissez votre type de thème.

    // MyTheme.ts
    
    export type MyTheme = {
      colors: {
        primary: string;
        background: string;
      };
    };
    
  • Utilisez le type sur vos thèmes.

    // themes.ts
    
    export const LightTheme: MyTheme = {
      colors: {
        primary: 'white',
        background: 'white',
      },
    };
    
    export const DarkTheme: MyTheme = {
      colors: {
        primary: 'grey',
        background: 'black',
      },
    };
    
  • Utilisez fusion de déclaration pour "fusionner" le type MyTheme dans le thème par défaut des composants stylisés.

    // styled.d.ts
    
    import 'styled-components';
    import { MyTheme } from '../src/themes/MyTheme';
    
    declare module 'styled-components' {
      // eslint-disable-next-line @TypeScript-eslint/no-empty-interface
      export interface DefaultTheme extends MyTheme {}
    }
    

OK cool. Le prop theme est correctement tapé.
Qu'en est-il des composants eux-mêmes?

  • Enveloppez vos accessoires de composant spécifiques dans le type StyledProps.

    import { StyledProps } from 'styled-components';
    import styled from 'styled-components/native';
    
    type MyViewProps = StyledProps<{
      backgroundColor?: string;
      isAlert?: boolean;
    }>;
    
    const MyView = styled.View(
      (props: MyViewProps) => `
        background-color: ${props.backgroundColor || props.theme.colors.background};
        color: ${props.isAlert ? red : props.theme.colors.primary}
      `,
    );
    

Dans cet exemple, les deux props.backgroundColor et props.theme.colors.background se terminera automatiquement. Lorsque vous mettez à jour le type MyTheme ou le type de composant spécifique, cela devrait simplement fonctionner. ????

component auto-complete

them auto-complete

0
GollyJer