Skip to content

Commit

Permalink
Generics to narrow types to item only when appropriate (deephaven#1909)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmingles committed Apr 2, 2024
1 parent b696bd1 commit b815f5a
Showing 1 changed file with 27 additions and 19 deletions.
46 changes: 27 additions & 19 deletions packages/components/src/spectrum/utils/itemUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ export type NormalizedSection = KeyedItem<
Key | undefined
>;

export type NormalizedItemOrSection<TItemOrSection extends ItemOrSection> =
TItemOrSection extends SectionElement ? NormalizedSection : NormalizedItem;

export type NormalizedSpectrumPickerProps = SpectrumPickerProps<NormalizedItem>;

export type TooltipOptions = { placement: PopperOptions['placement'] };
Expand Down Expand Up @@ -114,14 +117,19 @@ export function isItemElement<T>(
}

/**
* Determine if a node is an array containing normalized items with keys.
* Note that this only checks the first node in the array.
* Determine if a node is an array containing normalized items or sections with
* keys. Note that this only checks the first node in the array.
* @param node The node to check
* @returns True if the node is a normalized item with keys array
* @returns True if the node is a normalized item or section with keys array
*/
export function isNormalizedItemsWithKeysList(
node: ItemOrSection | ItemOrSection[] | (NormalizedItem | NormalizedSection)[]
): node is (NormalizedItem | NormalizedSection)[] {
export function isNormalizedItemsWithKeysList<
TItemOrSection extends ItemOrSection,
>(
node:
| TItemOrSection
| TItemOrSection[]
| NormalizedItemOrSection<TItemOrSection>[]
): node is NormalizedItemOrSection<TItemOrSection>[] {
if (!Array.isArray(node)) {
return false;
}
Expand Down Expand Up @@ -225,9 +233,9 @@ function normalizeTextValue(item: ItemElementOrPrimitive): string | undefined {
* @param itemOrSection item to normalize
* @returns NormalizedItem or NormalizedSection object
*/
function normalizeItem(
itemOrSection: ItemOrSection
): NormalizedItem | NormalizedSection {
function normalizeItem<TItemOrSection extends ItemOrSection>(
itemOrSection: TItemOrSection
): NormalizedItemOrSection<TItemOrSection> {
if (!isItemOrSection(itemOrSection)) {
log.debug(INVALID_ITEM_ERROR_MESSAGE, itemOrSection);
throw new Error(INVALID_ITEM_ERROR_MESSAGE);
Expand All @@ -244,7 +252,7 @@ function normalizeItem(

return {
item: { key, title, items },
};
} as NormalizedItemOrSection<TItemOrSection>;
}

const key = normalizeItemKey(itemOrSection);
Expand All @@ -255,23 +263,23 @@ function normalizeItem(

return {
item: { key, content, textValue },
};
} as NormalizedItemOrSection<TItemOrSection>;
}

/**
* Get normalized items from an item or array of items.
* @param itemsOrSections An item or array of items
* @returns An array of normalized items
* Normalize an item or section or a list of items or sections.
* @param itemsOrSections An item or section or array of items or sections
* @returns An array of normalized items or sections
*/
export function normalizeItemList(
itemsOrSections: ItemOrSection | ItemOrSection[] | NormalizedItem[]
): (NormalizedItem | NormalizedSection)[] {
export function normalizeItemList<TItemOrSection extends ItemOrSection>(
itemsOrSections: TItemOrSection | TItemOrSection[] | NormalizedItem[]
): NormalizedItemOrSection<TItemOrSection>[] {
// If already normalized, just return as-is
if (isNormalizedItemsWithKeysList(itemsOrSections)) {
return itemsOrSections;
return itemsOrSections as NormalizedItemOrSection<TItemOrSection>[];
}

const itemsArray = Array.isArray(itemsOrSections)
const itemsArray: TItemOrSection[] = Array.isArray(itemsOrSections)
? itemsOrSections
: [itemsOrSections];

Expand Down

0 comments on commit b815f5a

Please sign in to comment.