Maciej Kravchyk
Maciej Kravchyk

Reputation: 16647

Add a prefix to each type in a string union type

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'

Upvotes: 5

Views: 1036

Answers (2)

Behemoth
Behemoth

Reputation: 9330

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";

Upvotes: 9

MoxxiManagarm
MoxxiManagarm

Reputation: 9124

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

Upvotes: 2

Related Questions