typescript - 从枚举推断元组类型?
问题描述
export enum DataType {
UNKNOWN = 0x00,
STRING = 0x01,
FIXED_LENGTH_STRING = 0x02,
FLOAT32 = 0x03,
FLOAT64 = 0x04,
DECIMAL = 0x05,
NULLABLE_COMPACT_INT = 0x06,
}
export async function createTableWriteStream<T extends ReadonlyArray<any>>(path: string, options: FileOptions&TableWriteStreamOptions): Promise<TableWriteStream<T>> { ... }
const writeStream = await createTableWriteStream<[string,number|null|bigint]>(testFile, {
flags: 'w',
columns: [
{
name: "col1",
type: DataType.STRING,
},
{
name: "column 2",
type: DataType.NULLABLE_COMPACT_INT,
},
]
})
我想在DataType
和 TS 类型之间创建一个映射,这样我就不需要T
为createTableWriteStream
.
就像是:
interface TypeMap {
[DataType.UNKNOWN]: never,
[DataType.STRING]: string,
[DataType.FIXED_LENGTH_STRING]: string,
[DataType.FLOAT32]: number,
[DataType.FLOAT64]: number,
[DataType.DECIMAL]: number|string,
[DataType.NULLABLE_COMPACT_INT]: number|bigint|null,
}
但是我不知道如何使用它来推断createTableWriteStream
from的返回类型options.columns.type
。这可能吗?
解决方案
好的,这有点棘手。
首先,您需要准备从枚举到预期结果类型的映射。
type DataTypeMapping = {
[DataType.UNKNOWN]: never,
[DataType.STRING]: string,
[DataType.FIXED_LENGTH_STRING]: string,
[DataType.FLOAT32]: number,
[DataType.FLOAT64]: number,
[DataType.DECIMAL]: number|string,
[DataType.NULLABLE_COMPACT_INT]: number|bigint|null,
}
接下来,您需要创建一些类型,将您的源列元组映射到目标结果元组。现在(从 typescript 4.2.3 开始)将元组映射到另一个元组有点棘手,尤其是当您尝试将某些特定(非抽象)元组映射到另一个元组时。这是因为元组本身是一个数组,除了元素之外还有一些属性(如长度、数组方法、迭代器等)。以下是有效的构造:
type Tuple<T> = [T, ...T[]];
type MapDataTypeImpl<T extends Tuple<ColumnSpec>> = {
[K in keyof T]: T[K] extends ColumnSpec ? DataTypeMapping[T[K]['type']] : never
}
type MapDataType<T> = T extends Tuple<ColumnSpec> ? MapDataTypeImpl<T> : never;
(最初的想法是如何在 Typescript 3.0 中将元组“映射”到另一个元组类型)
MapDataType
您还可以在此处注意到使用和的两步实现MapDataTypeImpl
。我不知道确切原因,但目前似乎不可能将其合并为一种类型。
最后一步是使您的列成为元组
interface TableWriteStreamOptions {
columns: Tuple<ColumnSpec>
...
}
最后你可以像这样实现你的方法:
export async function createTableWriteStream<T extends TableWriteStreamOptions>(
path: string, options: FileOptions & T): Promise<TableWriteStream<MapDataType<T['columns']>>> {
// ...
return new TableWriteStream()
}
并且根据您的要求,现在createTableWriteStream
可以在没有显式类型参数的情况下使用。
这是一个工作示例。
推荐阅读
- powershell - powershell - 挖掘并强制使用 IPv6 或 IPv4
- shell - Unix 日期 当前日期 -(减号)日期(昨天日期)
- c++ - QListView 不显示模型中的数据
- javascript - 另一种在 html 中显示来自外部文件的内容的方法
- webrtc - webrtc使用哪种视频处理算法来提高视频质量
- geocoding - HERE Maps API - 收费
- python - 如何使用 AWS lambda 函数触发 AWS Sagemaker Jupyter 笔记本
- javascript - 当我不想时出现未保存更改的警报
- c# - Stack Exchange Redis 事务从不执行
- python - kivyMD:如何创建带有工具栏操作项的下拉菜单?