On a lib I working on, I have a ton of really annoying to write / read / maintain type generics, like this one :
type ResolveFieldType<K extends FormField<any>> = K extends {
options: _FieldOptions;
}
? ResolveOptionsField<K>
: K['type'] extends 'checkbox'
? ResolveCheckboxField<K>
: K['type'] extends 'object' | 'group'
? ResolveObjectField<K>
: K['type'] extends 'array-list' | 'array-tabs'
? ResolveArrayField<K>
: K['type'] extends 'upload'
? ResolveUploadField<K>
: K extends { type: 'array-variant' }
? ResolveArrayVariantField<K>
: ResolvePrimitiveField<K>;
I thought I could solve this by impelmenting a Match utility type that provides a better syntax for this, & came up with this :
type Match<T, Patterns extends (any[] | [any, any])[], Fallback = never> =
Patterns extends [infer First, ...infer Rest]
? First extends [infer NewSource, infer Condition, infer Result]
? [NewSource] extends [T]
? [NewSource] extends [Condition]
? Result
: Match<T, Rest extends (any[] | [any, any])[] ? Rest : never, Fallback>
: Match<T, Rest extends (any[] | [any, any])[] ? Rest : never, Fallback>
: First extends [infer Condition, infer Result]
? [T] extends [Condition]
? Result
: Match<T, Rest extends (any[] | [any, any])[] ? Rest : never, Fallback>
: never
: Fallback;