Property 'createMessageComponentCollector' does not exist on type 'GuildTextBasedChannel' - javascript

I ran into this strange problem, when I try to create a message component collector in a channel, it says:
Property 'createMessageComponentCollector' does not exist on type 'GuildTextBasedChannel'.
Property 'createMessageComponentCollector' does not exist on type 'StageChannel'
the interaction is the base CommandInteraction from discord.js. The strange part is I have another discord bot with using the same discord.js version (14), and there it works perfectly.
let cl = int.channel.createMessageComponentCollector();

Not sure if this will work but its worth a shot. Try checking the channel type before creating the collector.
import { ChannelType } from 'discord.js';
if(int.channel.type !== ChannelType.GuildText) return;
...
let cl = int.channel.createMessageComponentCollector();
If all else fails you can manually cast the type (generally not suggested).
import { GuildBasedTextChannel } from 'discord.js';
...
let cl = (int.channel as GuildBasedTextChannel).createMessageComponentCollector();
EDIT
To add on to Wesley LeMahieu's comment, and although it may be entirely unrelated, consider changing your command type from
CommandInteraction
to
ChatInputCommandInteraction<"cached">

Related

How to check if an exception is a FirebaseError / FirebaseAuthError in TypeScript

I'm trying to implement Firebase authentication and user creation on our server, working on TypeScript.
I'm creating a new user, and I have wrapped the whole creation inside a try-catch block. I'm trying to catch several exceptions, one of them being exception thrown by Firebase.
The problem is that I can't check if the exception was thrown by the Firebase, or if it's another type of exception.
Other answers to similar kind of questions suggest to check if the exception is an instance of FirebaseError:
let firebaseUser;
try {
firebaseUser = await firebase.auth().createUser({
email: email,
password: password,
});
// Other code here
} catch (error) {
if(error instanceof FirebaseError){
// handle FirebaseError here
}
}
The problem is, that when there is an error in the createUser function, the error is an instance of FirebaseAuthError, not FirebaseError, so this check fails.
I tried to switch it to FirebaseAuthError and import the FirebaseAuthError as well, but I get an error message:
Package subpath './lib/utils/error' is not defined by "exports" in
\node_modules\firebase-admin\package.json
So what would be the correct way to check that the caught exception is thrown by FirebaseAuth?
I think the best thing you can do, is writing a type guard to ensure your error is a FirebaseAuthError that you will import using import type. I checked, and it seems that it's because the library doesn't export it.
You can freely benefit from the type used by firebase, however, as the module is not listed in the exports, you won't be able to use it at runtime. the import type syntax allows you to still use it during development, but it will be completely ignored at build time.
That means you can't use instanceof FirebaseAuthError as only the type is imported, and you can't use instanceof on something else than a class.
I'm not sure about the following statement, but I guess that every error prefixed by auth/ seem to be a FirebaseAuthError.
Thus, you could write a type guard as follows:
import type { FirebaseAuthError } from 'firebase-admin/lib/utils/error';
function isFirebaseAuthError(error: FirebaseError): error is FirebaseAuthError {
return error.code.startsWith('auth/');
}

How to cast a variable to a particular type to convince typescript that everwhere?

For IE reasons I need to build a custom Error, however, as best as I can do it, the error has to be checked with the constructor.
customError instanceof CustomError; // false
customError.constructor === CustomError; // true
Now how can I convince typescript that in an if statement?
if (customError.constructor === CustomError) {
customError.customMethod1() // typescript complaints
customError.customMethod2() // typescript complaints
customError.customMethod3() // typescript complaints
customError.customMethod4() // typescript complaints
}
EDITED:
Background is when you are compiling down to ES5, some inheritances cannot be compatible.
Is there a way I can cast it once and not have to use as everytime I use the variable?
So far the only way to work with it is:
const myCustomError = (customError as CustomError)
Open to other bright ideas.
Write an User-Defined Type Guard:
function isCustomError(x: any): x is CustomError {
return x.constructor === CustomError;
}
And use it:
if (isCustomError(err)) {
err.customMethod1();
}
See this playground.

Intercepting and interracting with a custom Error object in javascript

I am using a custom javascript modulue which has it's own Error objects. I would like to intercept those custom Error objects and take the appropriate path in my try{} catch{} block, distinguishing them from Javascript's built in Error objects such as ReferenceError, TypeError etc.
So a bit like this.
try {
// Some code that might produce a traditional javascript error
// or one of the errors raised by the module I am using.
}catch (error){
if(error instanceof ExchangeError){
// Handle this in a way.
}else{
// Probably one of the built in Javascript errors,
// So do this other thing.
}
}
So, in the example above, ExchangeError is a custom error belonging to that specific module, however, I am not able to run the instanceof on my error, despite the fact that when I do error.constructor.name I get ExchangeError.
My javascript scope simply does not know about that ExchangeError. So the question is, how can I intercept those kind of Error objects? I'm sure I can do it with string matching, but just wanted to check if there is a more elegant way.
One thing I tried, I have my own errors module, that has some custom errors in there, I tried to mimic the module's Error object:
class ExchangeError extends Error {
constructor (message) {
super (message);
this.constructor = ExchangeError;
this.__proto__ = ExchangeError.prototype;
this.message = message;
}
}
and import that through my errors module, but that did not work obviously.
By actually implementing my own ExchangeError I actually was doing something really really bad, I was blinding the instanceof check with my own ExchangeError, whereas the ExchangeError instance that was coming from the module, was NOT an instance of my own ExchangeError. That is why my if check was falling silent.
The solution is simply doing this:
const { ExchangeError } = require ('ccxt/js/base/errors');
Importing the error from within the module. Now the instanceof look up is working. I did not know that one can import bits and pieces from a module like that.
Thanks to #FrankerZ for pointing that out.

Typescript compiler generates javascript even after compilation error

I am new to TypeScript and trying few basic stuffs. So I compile below app1.ts code
class Monster {
constructor(name, initialPosition) {
this.name = name;
this.initialPosition = initialPosition;
}
}
I believe we can add any properties to class Monster on fly like we can do in JS. So this.name and this.initialPosition should be a valid way. But as soon as I compile the code it has thrown below errors
app1.ts(3,14): error TS2339: Property 'name' does not exist on type
'Monster'.
app1.ts(4,14): error TS2339: Property 'initialPosition' does not exist
on type ' Monster'.
At this moment I thought we probably cannot add properties on fly (well, I got to know that we cannot do it like ECMA 6, we have to define properties - that's good) but when I check the generated JS it really surprised me. After compilation error it generated below JS code
var Monster = /** #class */ (function () {
function Monster(name, initialPosition) {
this.name = name;
this.initialPosition = initialPosition;
}
return Monster;
}());
I am a bit confuse. Why after compilation error it generated JS? What actually going on.
There are some types of errors relate to type checking that allow the compiler to emit JS. Just because the typescript compiler can't prove the program is typesafe does not mean it will not run. If the code can run it will be outputted to JS (so type errors allow emit, but syntactic ones do not)
There is a compiler option controlling this --noEmitOnError. You can read more here

Empty object after `require`

I'm trying to use your relaxed-json in my Electron app. Here is a simple code, GetDeviceList() is triggered on a button-push action:
const driver = require('meteor_driver').MeteorConnection.MeteorConnection;
const relaxed = require('relaxed-json');
const connection = new driver();
function GetDeviceList() {
console.log(connection.port);
console.log("Launching");
console.log(relaxed);
relaxed.transform('[{id:0,},{id:1,},{id:2,},]');
}
The console.log show me an empty object. And I got an error message Uncaught TypeError: relaxed.transform is not a function.
Otherwise, the package works properly when it's not used with electron.
Note that I don't encounter any require-related issue, so the modules must be valid isn't ?

Categories

Resources