我如何从类型中获取某些值的键?

How can I the take keys of some value from a type?

我尝试使用 csv-parse 的选项 cast 来转换类型。

我的做法如下,但是有问题

我参考了这个答案:

是否可以定义 KeysOfNumbers 和 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']),
});

这是一个方便的助手类型:

type KeysOfType<T, U> = {
    [K in keyof T]: T[K] extends U ? K : never
}[keyof T];

type TestA = KeysOfType<Mail, boolean>
// 'isRead' | 'isAD'

此类型需要一个要映射的对象 T,以及一个要保留的属性类型 U。它遍历每个键 K 并检查 属性 T[K] 的类型是否扩展 U。如果是,保留密钥,否则通过解析为 never 将其丢弃。最后通过自己的键索引结果对象,将所有 属性 类型作为一个联合。

现在您可以创建使用此类型的类型:

type KeysOfNumbers<T> = KeysOfType<T, number>[]
type KeysOfBooleans<T> = KeysOfType<T, boolean>[]

type MailNumbers = KeysOfNumbers<Mail>
//   ('Type' | 'Date')[]

type MailBooleans = KeysOfBooleans<Mail>
//   ('isRead' | 'isAD')[]

Playground