larswaechter / voici.js

A Node.js library for pretty printing your data on the terminal🎨

Home Page:https://voici.larswaechter.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Improve Type System

larswaechter opened this issue · comments

The goal is to improve the library's type system. Especially for the Config type.

An example:

When creating a config, you should only to be allowed to refer to the attributes defined in IData. For example when setting the sort's columns attribute, only the following values should be allowed: firstname, lastname and age, because they are attributes of IData.

import { Config, Table } from './';

interface IData {
  firstname: string;
  lastname: string;
  age: number;
}

const data: IData[] = [
  { firstname: 'Homer', lastname: 'Simpson', age: 39 },
  { firstname: 'Marge', lastname: 'Simpson', age: 36 },
  { firstname: 'Bart', lastname: 'Simpson', age: 10 },
  { firstname: 'Lisa', lastname: 'Simpson', age: 8 },
  { firstname: 'Maggie', lastname: 'Simpson', age: 1 }
];

const config: Config<IData> = {
  sort: {
    columns: ['age'], // only allow 'firstname', 'lastname' and 'age'
    directions: ['asc']
  }
};

const table = new Table(data, config);
table.print();

Unfortunately, this won't work for dynamic columns as these are not be defined in IData usually. That's why we have to pass the dynamic columns' names as generic type:

In this case, we are allowed to pick the fullname column for sorting.

interface IDynamicAttr {
  fullname: string;
}

const config: Config<IData, IDynamicAttr> = { // pass in 'IDynamicAttr'
  header: {
    dynamic: [
      {
        name: 'fullname',
        func: (row) => row.firstname + ' ' + row.lastname  // return value must match with interface
      }
    ]
  },
  sort: {
    columns: ['fullname'], // allow 'fullname' as well
    directions: ['asc']
  }
};