Final Project: Build a Typed Settings Validator
Combine utility types, narrowing, mapped/template literal types, and satisfies into one small but real module: a settings validator.
Requirements
- Define a
Settingsinterface with at least four fields of mixed types (e.g.theme: 'light' | 'dark',fontSize: number,autoSave: boolean,username: string). - Write an
isSettings(value: unknown): value is Settingstype predicate that validates an untrusted value (e.g. something parsed fromJSON.parse) before it's ever treated asSettings. - Write an
updateSettings(current: Settings, changes: Partial<Settings>): Settingsfunction, changes should be optional and partial, not a full replacement. - Use a mapped type to derive a
SettingsChangedtype,{ [K in keyof Settings]: boolean }, and a function that compares twoSettingsobjects and returns one, flagging exactly which fields differ. - Build a
defaultSettingsobject typed withsatisfies Settings, so each default value keeps its own precise type instead of being widened to a single union.
Stretch goals
- Add a template literal type deriving an event name per settings key, e.g.
on+ the capitalized key +Change, and a tiny typed event emitter that only accepts those names. - Use
Pick/Omitto derive a "public settings" type that hides one internal-only field from an exported API. - Add a
resetSettings(): Settingsthat returns a fresh copy ofdefaultSettings, and verify at the type level thatdefaultSettingsitself can't be mutated by accident.
Submit your repository link below when you are done, an instructor will review it before you can mark this lesson complete. Good luck! 🚀