10LOC

#in-operator

TypeScriptadvanced

Narrowing with in and tagged interfaces for a plugin system

interface LoggerPlugin { kind: "logger"; log(message: string): void }
interface CachePlugin { kind: "cache"; get(key: string): unknown }

export type AppPlugin = LoggerPlugin | CachePlugin;

Narrow a plugin union by checking which method it has, instead of switching on a kind tag, so adding a capability-only plugin needs no tag.