Is it possible to create a type from a union type where each element of the union will be transformed according to a pattern? I just need to put a prefix:
type EventNames = 'DragStart' | 'Drag' | 'DragStop'
type HandlerNames = Prefix<'on', EventNames> // 'onDragStart' | 'onDrag' | 'onDragStop'
CodePudding user response:
Yes, that is possible. Since TypesScript 4.1 you can use a Conditional Type in combination with a Template Literal Type like so:
type EventNames = "DragStart" | "Drag" | "DragStop";
type Prefix<K> = K extends string ? `on${K}` : K;
// --> "onDragStart" | "onDrag" | "onDragStop"
const myEvent: Prefix<EventNames> = "onDrag";
Or directly define the generic to extend string
in order to pass a prefix:
type EventNames = "DragStart" | "Drag" | "DragStop";
type Prefix<Prefix extends string, T extends string> = `${Prefix}${T}`;
const myEvent: Prefix<"on", EventNames> = "onDrag";
CodePudding user response:
type Prefix<P extends string, S extends string> = `${P}${S}`
type EventNames = 'DragStart' | 'Drag' | 'DragStop'
type HandlerNames = Prefix<'on', EventNames> // 'onDragStart' | 'onDrag' | 'onDragStop'
const handler1: HandlerNames = 'onDrag';
const handler2: HandlerNames = 'onDraggo'; // error!
See stackblitz:https://stackblitz.com/edit/typescript-98syrf?file=index.ts