type EventName < T extends string > = `${ T }Changed` ; type T0 = EventName < 'foo' > ; type T1 = EventName < 'foo' | 'bar' | 'baz' > ; type T2 = `${ 'top' | 'middle' | 'bottom' }-${ 'left' | 'center' | 'right' }` ; type StringDashString = `${ string }-${ string }` ; type StringDashNumber = `${ string }-${ number }` ; let sds = 'hello-world' ; let sdn = 'hello-42' ; type Trim < S extends string > = S extends ` ${ infer T }` ? Trim < T > : S extends `${ infer T } ` ? Trim < T > : S ; type T20 = Trim < '     hello   ' > ; type T21 = Trim < ' hello           ' > ; type Placeholders < T extends string > = T extends `${ string }{${ infer P }}${ infer R }` ? P | Placeholders < R > : never ; declare function format < S extends string > ( template , args ) ; let text = format ( 'Name: {name}, Age: {age}' , { name : 'Homer' , age : 42 } ) ; type RouteParamName < T extends string > = string extends T ? string : T extends `${ string }:${ infer P }/${ infer R }` ? P | RouteParamName < R > : T extends `${ string }:${ infer P }` ? P : never ; declare function handleGet < R extends string > ( route , handler ) ; handleGet ( '/posts/:postId/:commentId' , params => { } ) ; type PathKeys < T > = object extends T ? string : T extends readonly any [ ] ? Extract < keyof T , `${ number }` > | SubKeys < T , Extract < keyof T , `${ number }` > > : T extends object ? Extract < keyof T , string > | SubKeys < T , Extract < keyof T , string > > : never ; type SubKeys < T , K extends string > = K extends keyof T ? `${ K }.${ PathKeys < T [ K ] > }` : never ; type PropType < T , Path extends string > = Path extends keyof T ? T [ Path ] : Path extends `${ infer K }.${ infer R }` ? K extends keyof T ? PropType < T [ K ] , R > : unknown : unknown ; declare function getProp < T , P extends PathKeys < T > > ( obj , path ) ; const obj = { name : 'John' , age : 42 , cars : [ { make : 'Ford' , age : 10 } , { make : 'Trabant' , age : 35 } ] } as const ; let make = getProp ( obj , 'cars.1.make' ) ; type OnPropChangedMethods < T > = { [ P in keyof T & string as `${ P }Changed` ] : ( cb : ( newValue : T [ P ] ) => void ) => void ; } ; declare function makeWatchedObject < T > ( obj ) ; let homer = makeWatchedObject ( { firstName : "Homer" , age : 42 , location : "Springfield" , } ) ;