0

i have problem with task relaying on format Y axis to display only natural numbers. In project i am using React awith Typescript and Nivo Rocks library to create charts (https://nivo.rocks/).for the purpose of this question i created sandbox:

https://codesandbox.io/s/scuqn?file=/src/App.tsx

i found a solution to set format:

  axisLeft={{
    format: e => Math.floor(e) === e && e
  }}
/>

but it works only with pure js (no type checking). with TS there is a type error (with 'e:number'):

No overload matches this call.
  Overload 1 of 2, '(props: LineSvgProps | Readonly<LineSvgProps>): ResponsiveLine', gave the following error.
    Type '(e: number) => number | undefined' is not assignable to type 'string | TickFormatter | undefined'.
      Type '(e: number) => number | undefined' is not assignable to type 'TickFormatter'.
        Types of parameters 'e' and 'value' are incompatible.
          Type 'string | number | Date' is not assignable to type 'number'.
            Type 'string' is not assignable to type 'number'.
  Overload 2 of 2, '(props: LineSvgProps, context: any): ResponsiveLine', gave the following error.
    Type '(e: number) => number | undefined' is not assignable to type 'string | TickFormatter | undefined'.
      Type '(e: number) => number | undefined' is not assignable to type 'TickFormatter'.ts(2769)

i can't match types to this solution and i can't use 'any' type, i am starting to believe the library creators didn't predict this problem in their library ;) if anyone can help me with these or suggest another solution i will be greatful :)

Zygmaister
  • 43
  • 4

1 Answers1

0

That's because the signature of your custom function does not match the one the library is expecting. In this case, your function should match the signature of TickFormatter:

export type TickFormatter = (value: number | string | Date) => string | number

As you can see, there are multiple incompatibilities between your function and the one the library is expecting. First, you're saying your value can only be a number but the library says value can also be a string or even a Date object. Second, your function can return undefined while the library expected a function that can only return string or number.

Also, like you said, using any here would be a bad practice since you would be exposing yourself to receive and use incorrect data types.

The easiest solution here would just be refactoring your custom Y axis formatter function and make it compatible with what the library is expecting. For example, if you're 100% sure you're only gonna receive numbers in this function:

const yformat = (e: number | string | Date) => {
  if (typeof e === 'number') {
    return Math.floor(e);
  } else {
    throw new Error('Unexpected value');
  }
};
Lars
  • 554
  • 1
  • 5
  • 19