reactjstypescripttypesnivo-reactindex-signature

Typescript: How to define a type for unknown quantity of record patterns


I'm trying to use Nivo charts with typescript and I'm not sure how to define the type of data Nivo expects for their Bar Chart. (https://Nivo.Rocks)

I've been trying to use

  1. Object Index Signature ... {[Key: string]: string;}
  2. Record utility type ... Record<string, string>

A snippet of example data from Nivo is as folllows:

data = [
    {
        country: 'AD',
        'hot dog': 111,
        'hot dogColor': 'hsl(168, 70%, 50%)',
        burger: 19,
        burgerColor: 'hsl(123, 70%, 50%)',
        sandwich: 161,
        sandwichColor: 'hsl(91, 70%, 50%)',
        kebab: 199,
        kebabColor: 'hsl(347, 70%, 50%)',
        fries: 153,
        friesColor: 'hsl(346, 70%, 50%)',
        donut: 41,
        donutColor: 'hsl(96, 70%, 50%)',
    }
];

I attempted things similar to this...

export type NivoBarData = {
    [Key: string]: string;
    [Key: string]: number;
    nodeKeyValue?: NivoBarNodeValue;
    nodeColor?: NivoBarNodeColor;
};

export type NivoBarTitle = Record<string, string>;
export type NivoBarNodeColor = { [Key: string]: string };
export type NivoBarNodeValue = { [Key: string]: number };

Solution

  • You could improve the type by adding in the association of keys ending with Color to strings that represent colors using an intersection and template literal types:

    type NivoDatum = {
        [key: `${string}Color`]: string;
    } & {
        [key: string]: string | number;
    };
    

    Then it'll correctly error on incorrect types:

    const datum: NivoDatum = {
        donut: 41,          // ok since it's not a color
        donutColor: 111111, // not a string
    };
    

    Playground

    Maybe I'll make a PR or open an issue about this later?