Type Alias UpdateFilter<Base, Mod, State>

UpdateFilter<Base, Mod, State>: ((update: Base, state?: UpdateState<State>) => MaybePromise<boolean>)

Type describing a primitive filter, which is a function taking some Base and a TelegramClient, checking it against some condition and returning a boolean.

If true is returned, the filter is considered to be matched, and the appropriate update handler function is called, otherwise next registered handler is checked.

Additionally, filter might contain a type modification to Base for better code insights. If it is present, it is used to overwrite types (!) of some of the Base fields to given (note that this is entirely compile-time! object is not modified)

For parametrized filters (like filters.regex), type modification can also be used to add additional fields (in case of regex, its match array is added to .match)

Example without type mod:


const hasPhoto: UpdateFilter<Message> = msg => msg.media?.type === 'photo'

// ..later..
tg.onNewMessage(hasPhoto, async (msg) => {
// `hasPhoto` filter matched, so we can safely assume
// that `msg.media` is a Photo.
//
// but it is very redundant, verbose and error-rome,
// wonder if we could make typescript do this automagically and safely...
await (msg.media as Photo).downloadToFile(`${msg.id}.jpg`)
})

Example with type mod:


const hasPhoto: UpdateFilter<Message, { media: Photo }> = msg => msg.media?.type === 'photo'

// ..later..
tg.onNewMessage(hasPhoto, async (msg) => {
// since `hasPhoto` filter matched,
// we have applied the modification to `msg`,
// and `msg.media` now has type `Photo`
//
// no more redundancy and type casts!
await msg.media.downloadToFile(`${msg.id}.jpg`)
})

Note: Type modification can contain anything, even totally unrelated types and it is your task to keep track that everything is correct.

Bad example:

// we check for `Photo`, but type contains `Audio`. this will be a problem!
const hasPhoto: UpdateFilter<Message, { media: Audio }> = msg => msg.media?.type === 'photo'

// ..later..
tg.onNewMessage(hasPhoto, async (msg) => {
// oops! `msg.media` is `Audio` and does not have `.width`!
console.log(msg.media.width)
})

Warning! Do not use the generics provided in functions like and, or, etc. Those are meant to be inferred by the compiler!

Type Parameters

  • Base
  • Mod = {}
  • State extends object = never