valid,invalid

関心を持てる事柄について

React AdminのExporter type definitionを修正した

React AdminにはExporterという機能がある。

Exporter feature

https://marmelab.com/react-admin/doc/3.10/List.html#exporter にならってjsonexportのようなライブラリと組み合わせれば数行〜数十行のコードでリストをCSV等で出力できる。

// in PostList.js
import { List, downloadCSV } from 'react-admin';
import jsonExport from 'jsonexport/dist';

const exporter = posts => {
    const postsForExport = posts.map(post => {
        const { backlinks, author, ...postForExport } = post; // omit backlinks and author
        postForExport.author_name = post.author.name; // add a field
        return postForExport;
    });
    jsonExport(postsForExport, {
        headers: ['id', 'title', 'author_name', 'body'] // order fields in the export
    }, (err, csv) => {
        downloadCSV(csv, 'posts'); // download as 'posts.csv` file
    });
};

const PostList = props => (
    <List {...props} exporter={exporter}>
        ...
    </List>
)

ドキュメント

型定義によれば ExporterPromise<void> を返す関数である。

# https://github.com/marmelab/react-admin/blob/9cc5e83252455b5e3e172306419431716f17a057/packages/ra-core/src/types.ts#L492-L501
export type Exporter = (
    data: any,
    fetchRelatedRecords: (
        data: any,
        field: string,
        resource: string
    ) => Promise<any>,
    dataProvider: DataProvider,
    resource?: string
) => Promise<void>;

また、jsonexportvoidを返す関数である。

# https://github.com/DefinitelyTyped/DefinitelyTyped/blob/40e88087e9ec5898250644da6e4653888905bd85/types/jsonexport/index.d.ts#L112-L116
declare function jsonexport(
    json: object | object[],
    userOptions: jsonexport.UserOptionsWithHandlers,
    cb: (err: Error, csv: string) => void,
): void;

なのでドキュメントの例のexporter関数は Exporter 型にマッチしない。Promiseでラップしてやる必要がある、というのに同僚が気付いてくれた。

ドキュメント修正

ドキュメントもpublic repositoryで管理されているのでcontribution chanceと思って修正pull requestを送ってみた。

github.com

すると、型定義がそもそも間違っているのでそっちを直してくれとのことだった。

型定義の修正

直した。次のpatch updateであるv3.11.3でshipされそうだ。

github.com

export type Exporter = (
    data: any,
    fetchRelatedRecords: (
        data: any,
        field: string,
        resource: string
    ) => Promise<any>,
    dataProvider: DataProvider,
    resource?: string
-) => Promise<void>;
+) => void | Promise<void>;

今回ドキュメントを修正する際に気付いたのだが、充実しているかに見えたReact Adminのドキュメントは2~3年前の記述が残っていたり、TypeScript時代に対応していなかったりする。

React Adminは2020年から型定義の提供や内部実装のTypeScript化を開始しており、まだ途上と思える箇所も色々見つかりそうだ。


This article is for ohbarye Advent Calendar 2020.