I tried to use csv-parse's option cast
to convert the type.
My approach is as follows, but there are problems.
I referred to this answer: https://stackoverflow.com/a/60932900/19252706
Is it to possible to define KeysOfNumbers and KeysOfBooleans:
import {CastingFunction, parse} from 'csv-parse/browser/esm/sync';
const input =
'ID,Type,From,Title,Content,Date,IsRead,IsAD\r\n1,0,Mars,My car glass was broken,How much DOGE to fix this.....,423042301654134900000,false,false';
type Mail = {
ID: string;
Type: number;
From: string;
Title: string;
Content: string;
Date: number;
isRead: boolean;
isAD: boolean;
};
// This is problem. Is this possible to fix?
type KeysOfNumbers<T> = string[];
type KeysOfBooleans<T> = string[];
const castNumberAndBoolean =
<T>(
keysOfNumbers: KeysOfNumbers<T>,
KeysOfBooleans: KeysOfBooleans<T>,
): CastingFunction =>
(value, context) =>
keysOfNumbers.includes(context.column.toString())
? Number(value)
: KeysOfBooleans.includes(context.column.toString())
? value === 'true'
? true
: false
: value;
parse(input, {
columns: true,
cast: castNumberAndBoolean<Mail>(['Type', 'Date'], ['isRead', 'isAD']),
});
This is a handy helper type:
This type takes an object to map
T
, and a type for the properties to keepU
. It iterates over each keyK
and checks if the type of that propertyT[K]
extendsU
. If it does, keep the key, else throw it out by resolving tonever
. Lastly index the resulting object by its own keys to get all property types as a union.Now you can make types that use this type:
Playground