mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 12:09:26 +00:00
Added comments to explain the Typescript metaprogramming
This commit is contained in:
@@ -1,16 +1,21 @@
|
||||
import { LitElement } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
|
||||
// Match event types that are registered on GlobalEventHandlersEventMap...
|
||||
type EventTypeRequiresDetail<T> = T extends keyof GlobalEventHandlersEventMap
|
||||
? GlobalEventHandlersEventMap[T] extends CustomEvent<Record<PropertyKey, unknown>>
|
||||
? GlobalEventHandlersEventMap[T] extends CustomEvent<Record<PropertyKey, never>>
|
||||
? // ...where the event detail is an object...
|
||||
GlobalEventHandlersEventMap[T] extends CustomEvent<Record<PropertyKey, unknown>>
|
||||
? // ...that is non-empty...
|
||||
GlobalEventHandlersEventMap[T] extends CustomEvent<Record<PropertyKey, never>>
|
||||
? never
|
||||
: Partial<GlobalEventHandlersEventMap[T]['detail']> extends GlobalEventHandlersEventMap[T]['detail']
|
||||
: // ...and has at least one non-optional property
|
||||
Partial<GlobalEventHandlersEventMap[T]['detail']> extends GlobalEventHandlersEventMap[T]['detail']
|
||||
? never
|
||||
: T
|
||||
: never
|
||||
: never;
|
||||
|
||||
// The inverse of the above (match any type that doesn't match EventTypeRequiresDetail)
|
||||
type EventTypeDoesNotRequireDetail<T> = T extends keyof GlobalEventHandlersEventMap
|
||||
? GlobalEventHandlersEventMap[T] extends CustomEvent<Record<PropertyKey, unknown>>
|
||||
? GlobalEventHandlersEventMap[T] extends CustomEvent<Record<PropertyKey, never>>
|
||||
@@ -21,15 +26,22 @@ type EventTypeDoesNotRequireDetail<T> = T extends keyof GlobalEventHandlersEvent
|
||||
: T
|
||||
: T;
|
||||
|
||||
// `keyof EventTypesWithRequiredDetail` lists all registered event types that require detail
|
||||
type EventTypesWithRequiredDetail = {
|
||||
[EventType in keyof GlobalEventHandlersEventMap as EventTypeRequiresDetail<EventType>]: true;
|
||||
};
|
||||
|
||||
// `keyof EventTypesWithRequiredDetail` lists all registered event types that do NOT require detail
|
||||
type EventTypesWithoutRequiredDetail = {
|
||||
[EventType in keyof GlobalEventHandlersEventMap as EventTypeDoesNotRequireDetail<EventType>]: true;
|
||||
};
|
||||
|
||||
// Helper to make a specific property of an object non-optional
|
||||
type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
|
||||
|
||||
// Given an event name string, get a valid type for the options to initialize the event that is more restrictive
|
||||
// than just CustomEventInit when appropriate (validate the type of the event detail, and require it to be
|
||||
// provided if the event requires it)
|
||||
type SlEventInit<T> = T extends keyof GlobalEventHandlersEventMap
|
||||
? GlobalEventHandlersEventMap[T] extends CustomEvent<Record<PropertyKey, unknown>>
|
||||
? GlobalEventHandlersEventMap[T] extends CustomEvent<Record<PropertyKey, never>>
|
||||
@@ -40,6 +52,7 @@ type SlEventInit<T> = T extends keyof GlobalEventHandlersEventMap
|
||||
: CustomEventInit
|
||||
: CustomEventInit;
|
||||
|
||||
// Given an event name string, get the type of the event
|
||||
type GetCustomEventType<T> = T extends keyof GlobalEventHandlersEventMap
|
||||
? GlobalEventHandlersEventMap[T] extends CustomEvent<unknown>
|
||||
? GlobalEventHandlersEventMap[T]
|
||||
|
||||
Reference in New Issue
Block a user