好吧,这有点棘手。
首先,您需要准备从枚举到预期结果类型的映射。
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;
(最初的想法归功于
How to 'map' a Tuple to another Tuple type in 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
可以在没有显式类型参数的情况下使用。
这是一个
working example
.