Template Literal Types

type EmailLocaleIDs = “welcome_email” | “email_heading”; type FooterLocaleIDs = “footer_title” | “footer_sendoff”;

type AllLocaleIDs = ${EmailLocaleIDs | FooterLocaleIDs}_id; type AllLocaleIDs = “welcome_email_id” | “email_heading_id” | “footer_title_id” | “footer_sendoff_id”

type AllLocaleIDs = ${EmailLocaleIDs | FooterLocaleIDs}_id; type Lang = “en” | “ja” | “pt”; type LocaleMessageIDs = ${Lang}_${AllLocaleIDs};

type LocaleMessageIDs = “en_welcome_email_id” | “en_email_heading_id” | “en_footer_title_id” | “en_footer_sendoff_id” | “ja_welcome_email_id” | “ja_email_heading_id” | “ja_footer_title_id” | “ja_footer_sendoff_id” | “pt_welcome_email_id” | “pt_email_heading_id” | “pt_footer_title_id” | “pt_footer_sendoff_id”

type PropEventSource = { on(eventName: ${string & keyof Type}Changed, callback: (newValue: any) => void): void; };

/// Create a “watched object” with an on method /// so that you can watch for changes to properties. declare function makeWatchedObject(obj: Type): Type & PropEventSource;

const person = makeWatchedObject({ firstName: “Saoirse”, lastName: “Ronan”, age: 26 });

person.on(“firstNameChanged”, () => {});

// Prevent easy human error (using the key instead of the event name) person.on(“firstName”, () => {}); Argument of type ‘“firstName”’ is not assignable to parameter of type ‘“firstNameChanged” | “lastNameChanged” | “ageChanged”‘.

// It’s typo-resistant person.on(“frstNameChanged”, () => {}); Argument of type ‘“frstNameChanged”’ is not assignable to parameter of type ‘“firstNameChanged” | “lastNameChanged” | “ageChanged“‘.

type Greeting = “Hello, world” type ShoutyGreeting = Uppercase

type ShoutyGreeting = “HELLO, WORLD”

type ASCIICacheKey = ID-${Uppercase<Str>} type MainID = ASCIICacheKey<“my_app”>

type MainID = “ID-MY_APP”