5 votes

Erreur : Le type 'number | undefined' n'est pas assignable au type 'number | { valueOf(): number; }' ?

J'ai ce type de tableau :

interface Details {
  Name: string;
  URL: string;
  Year: number;
}
interface AppState {
  data: Details[];
}

J'utilise D3 pour créer un axe des x de cette manière :

 createChart = () => {
    const { data } = this.state;
    const width = 900,
      height = 600;

    // axe des x
    const x = d3
      .scaleLinear()
      .domain([
        d3.min(data, ({ Year }) => (Year ? Year - 1 : 0)), // ERREUR
        d3.max(data, ({ Year }) => (Year ? Year + 1 : 0)) // ERREUR
      ])
      .range([0, width]);
  };

Sur les lignes marquées en utilisant d3.min et d3.max, je reçois l'erreur suivante :

Le type 'number | undefined' n'est pas assignable au type 'number | {valueOf(): number;}'. Le type 'undefined' n'est pas assignable au type 'number | {valueOf(): number;}'.

Comment puis-je faire fonctionner cela ?

9voto

altocumulus Points 13034

Pour votre appel à d3.min(), le compilateur utilisera la définition de type suivante :

export function min(array: Iterable, accessor: (datum: T, index: number, array: Iterable) => U | undefined | null): U | undefined;

Comme vous pouvez le voir, la fonction peut retourner soit U - dans votre cas le type de Details.Year, c'est-à-dire number - soit undefined. Cependant, cela ne correspond pas à la définition de type pour la méthode .domain() qui prend un tableau de nombres ou de valeurs coercibles en nombres :

domain(domain: Array): this;

Cela explique pourquoi vous obtenez l'erreur. De même, cela est vrai pour d3.max().

En regardant la documentation, les raisons pour lesquelles d3.min() retourne undefined sont plutôt limitées :

Si l'itérable ne contient pas de valeurs comparables, retourne undefined.

Étant donné votre code, vous êtes assuré de ne pas rencontrer ce problème. Pour cette raison, vous pouvez en toute sécurité convertir les valeurs de retour de d3.min() et d3.max() en number :

const x = d3
  .scaleLinear()
  .domain([
    d3.min(data, ({ Year }) => (Year ? Year - 1 : 0)) as number,  // convertir en number
    d3.max(data, ({ Year }) => (Year ? Year + 1 : 0)) as number   // convertir en number
  ])
  .range([0, width]);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X