telegraf: Typescript: Context message does not contain text
Hello everyone, before starting this thread I would love to introduce my setup
- Telegraf.js Version: 4.0.1
- Node.js Version: 14
- Operating System: OSX or Linux
The main problem is when I am using TypeScript It’s not possible to access on Text property from the message itself.
import { Context } from 'telegraf';
// *** [More code...] ***
bot.on(['text', 'edited_message'], (ctx: Context) => {
const msg = ctx.message ?? ctx.editedMessage;
console.log(msg.text) // We will read the message text into the console
});
This will throw a typescript error described below.
TS2339: Property 'text' does not exist on type '(New & NonChannel & TextMessage) | (New & NonChannel & DocumentMessage) | (New & NonChannel & AudioMessage) | ... 54 more ... | (Edited & ... 1 more ... & VoiceMessage)'. Property 'text' does not exist on type 'New & NonChannel & DocumentMessage'.
And this is my tsconfig.json
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Node 14",
"compilerOptions": {
"module": "commonjs",
"lib": ["es2020"],
"esModuleInterop": true,
"removeComments": true,
"allowSyntheticDefaultImports": true,
"target": "es6",
"noImplicitAny": true,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "build",
"baseUrl": ".",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"paths": {
"*": [
"node_modules/*",
"src/types/*"
]
}
},
"include": [
"src/**/*"
],
"exclude": [
"__tests__"
]
}
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 20 (10 by maintainers)
Commits related to this issue
- bot/start,jobs/pending_payments: convert ts to js Co-authored-by: Parham <parhaamsaremi@gmail.com> — committed to parhamsaremi/bot by tehraninasab a year ago
- Add `deunionize`, closes #1319 — committed to PabloWenger/telegraf by wojpawlik 3 years ago
Preferably, use
.on('text'). If there’s noupdateTypeyou want, use.guard, or narrow down manually:Then TypeScript knows that
ctx.message.textis present, and thus for examplectx.message.photomust be absent.Would this satisfy you?
I have 2 implementations already, sadly neither works on
Chat, I can work on that.I don’t dislike it. I’m just unable to allow it without requiring non-null assertions everywhere else. PR welcome.
@YakovL See https://github.com/telegraf/telegraf/issues/1388#issuecomment-791573609
https://github.com/tdlib/telegram-bot-api/issues/93 would allow
Not perfect, but worked well on everything I threw at it:
I’ll ship it in 4.1 so that people can improve it via pull requests.
It’s good that we can have it, but it still feels a bit ‘hacky’. I’ll spend some time and check typings in repo, but if it’s impossible to avoid non-null assertions, then your solution looks good
I still can’t get what is the problem to always have a
textin message? You can use 3.38 version without non-null assertions:It looks like you’re trying to remove possible fields form type, but these fields are exist it this type, based on telegram-typings and on telegram official docs.
Also based on typescript handbook there is no any sense to remove optional properties from interfaces. There is makes sense to clarify types like this:
My point here is that maybe you should consider not removing optional fields from interfaces and fix nullability with more specific contexts interfaces.
Not every edited message is edited text message (#1218).
For now, narrow it down manually with
if (!("text" in msg)) return next()or usebot.guard.