diff --git a/example.xlsx b/example.xlsx index fb97455..30ce030 100644 Binary files a/example.xlsx and b/example.xlsx differ diff --git a/src/index.ts b/src/index.ts index ac3c852..3d9701c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import xlsx, { type IColumn, type IJsonSheet, getWorksheetColumnWidths } from 'j import type { CellStyle } from 'xlsx-js-style' import XLSX from 'xlsx-js-style' import { deepmerge } from 'deepmerge-ts' -import type { CellValue, Column, ColumnGroup, ExcelSchema, GenericObject, NestedPaths, Not, Sheet, TransformersMap, ValueTransformer } from './types' +import type { CellValue, Column, ColumnGroup, ExcelSchema, GenericObject, NestedPaths, Not, SchemaColumnKeys, Sheet, TransformersMap, ValueTransformer } from './types' import { formatKey, getPropertyFromPath, getSheetCellKey } from './utils' export class ExcelSchemaBuilder< @@ -85,7 +85,7 @@ export class ExcelSchemaBuilder< } export class ExcelBuilder { - private sheets: Array>> = [] + private sheets: Array, any, any>> = [] public static create(): ExcelBuilder { return new ExcelBuilder() @@ -95,9 +95,11 @@ export class ExcelBuilder { Key extends string, T extends GenericObject, Schema extends ExcelSchema, + ColKeys extends SchemaColumnKeys, + SelectCols extends { [key in ColKeys]?: boolean } = {}, >( key: Not, - sheet: Omit, 'sheetKey'>, + sheet: Omit, 'sheetKey'>, ): ExcelBuilder { if (this.sheets.some(s => s.sheetKey === key)) throw new Error(`Sheet with key '${key}' already exists.`) diff --git a/src/types.ts b/src/types.ts index 36fd970..1401305 100644 --- a/src/types.ts +++ b/src/types.ts @@ -27,6 +27,10 @@ export type TypeFromPath = : never : never +export type AllKeysMatch = { + [K in keyof T]: T[K] extends U ? true : false; +}[keyof T] extends true ? true : false + export type CellValue = string | number | boolean | null | undefined | Date export type ValueTransformer = (value: any) => CellValue @@ -109,12 +113,36 @@ export type SchemaColumnKeys< export type Sheet< T extends GenericObject, Schema extends ExcelSchema, + ColumnKeys extends SchemaColumnKeys, + SelectColsMap extends { [key in ColumnKeys]?: boolean } | never, + SelectedCols extends string = ExtractSelectedColumns, + ContextMap extends { [key: string]: any } = ExtractContextMap, + SelectedContextMap extends ExtractSelectedContext = ExtractSelectedContext, > = { sheetKey: string schema: Schema data: T[] - select?: { [K in SchemaColumnKeys]?: boolean } + select?: SelectColsMap context?: {} -} & (Schema extends ExcelSchema - ? keyof Ctx extends never ? {} : { context: Ctx } - : {}) +} & (keyof SelectedContextMap extends never ? {} : { context: SelectedContextMap }) + +export type ExtractContextMap< + Schema extends ExcelSchema, +> = Schema extends ExcelSchema ? Ctx : {} + +export type ExtractSelectedColumns< + ColKeys extends string, + SelectCols extends { [key in ColKeys]?: boolean }, +> = keyof SelectCols extends never ? ColKeys : + AllKeysMatch extends true + ? Exclude + : { + [K in ColKeys]: SelectCols[K] extends true ? K : never; + }[ColKeys] + +export type ExtractSelectedContext< + ContextMap extends { [key: string]: any }, + SelectedCols extends string, +> = { + [K in keyof ContextMap as K extends SelectedCols ? K : never]: ContextMap[K]; +} diff --git a/test/index.test.ts b/test/index.test.ts index 3c438b7..f969869 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -99,23 +99,25 @@ describe('should', () => { .sheet('sheet1', { data: users, schema: assessmentExport, + select: { + 'group:org': true, + }, context: { 'group:org': organizations, - }, + }) .sheet('sheet2', { data: users, schema: assessmentExport, select: { - firstName: true, - lastName: true, - email: true, - // 'group:org': true, + 'firstName': true, + 'lastName': false, + 'email': false, + 'group:org': false, }, context: { - 'group:org': organizations, - + // 'group:org': organizations, }, }) .sheet('sheet3', {