Hallo!
Kurz gesagt führt der Aufruf einer beliebigen API mit einem Parameter, der explizit den Wert undefined
angibt, dazu, dass er an VK übergeben wird. Unten ist ein Beispiel.
await ctx.send("it'll fail", {
keyboard: undefined
});
ctx
- Ereigniskontext message_new
Parameter mit dem Wert undefined
sollten nicht übergeben werden, genauso wie wenn sie weggelassen würden.
VK-IO übersetzt undefined
in einen String und übergibt ihn an den Server.
| Paket | Version |
| ---------------------------------- | -------- |
| vk-io
| 4.0.1
|
| node
| 12.17.0
|
| TypeScript
| 4.0.2
|
| yarn
| 1.22.4
|
Nein, warte, ein bisschen funktioniert das nicht. Dir erklären?
Komm schon, was ist ein bisschen los?
Dass die Parameter mit URLSearchParams gesendet werden
const params = {
message: 'hello',
keyboard: undefined
};
console.log(new URLSearchParams(params));
// Выведет: URLSearchParams { 'message' => 'hello', 'keyboard' => 'undefined' }
@isinkin Ja, aber ich habe bereits in PR geschrieben, dass dies ein Bug ist, da TypeScript überhaupt keinen Unterschied macht, der Parameter nicht oder mit dem Wert undefined
, aber zur Laufzeit dies schon führt zu einem API-Fehler. Dies ist eine Art direkter Fallstrick.
@zardoy warum ist das ein Fehler?
const obj = {
key: undefined,
}
const properties = Object.getOwnPropertyNames(obj)
console.log(properties)
Die Eigenschaft ist deklariert, ihr Typ ist undefiniert, und wenn sie in eine Zeichenfolge umgewandelt wird, wird die Zeichenfolge 'undefiniert' erhalten.
Dass bei ts etwas nicht gut läuft gilt schon für ts, die Laufzeit ist in der Regel auf v8 und unterstützt nur Javascript.
const obj = { key: undefined, } const properties = Object.getOwnPropertyNames(obj) console.log(properties)
Das ist richtig, aber warum ist diese Transformation? Wenn wir einen String mit einem solchen Inhalt explizit übergeben möchten, warum übergeben Sie den String dann nicht explizit als Parameter?
vk.api.messages.send({
message: "undefined" // - так ок
});
Vielleicht haben Sie Recht, dass dies kein Fehler ist, sondern nur ein Fallstrick, da ts keinen Kompilierungsfehler auslöst, wenn Sie undefined
explizit angeben. Mein Vorschlag in PR ist jedoch, dass das Verhalten, wenn wir den Parameter vollständig weglassen und undefined
angeben, dasselbe wäre, weil nicht immer
Sori, die ich geschlossen habe, werde ich jetzt hinzufügen.
@zardoy ich verstehe was du meinst.
Sicher schreibst du sowas wie
let someVariable;
const query = {
key: someVariable,
}
send(query)
Ich denke, dieses Problem liegt auf der Benutzerseite, Sie müssen anders schreiben, und mit diesem Pr brechen Sie die Abwärtskompatibilität.
Ich denke, dieses Problem liegt auf der Benutzerseite, Sie müssen anders schreiben, und mit diesem Pr brechen Sie die Abwärtskompatibilität.
Ich stimme zu.
Schauen Sie einfach, wo der Hund begraben ist (ein anschaulicheres Beispiel):
Ich könnte es nicht so buchstabieren
das kann ich schon
ts wird gut fluchen, obwohl die Bitte tatsächlich dieselbe sein wird. Nur eine Falle für den Benutzer
@zardoy, also schreibe nichts, wenn du diesen Parameter nicht übergeben möchtest, es wird so funktionieren, wie du es willst
vk.api.messages.send()
Es liegt eher ein Missverhältnis des Verhaltens vor, wobei JSON.stringify()
undefined
übersehen wird. Während URLSearchParams
alles zu einem String führt. Dadurch wird die Abwärtskompatibilität nicht beeinträchtigt, da undefined
überprüft wird, nicht "undefined"
.
Aber jetzt verlieren wir interessante Nachrichten im Chat in Form von undefined
:)
@negezor über solche Nachrichten meinte ich, es ist möglich, dass jemand den undefinierten Typ verwendet, wenn er solchen Text drucken möchte)
upd: Nun, statt undefined wird in einigen Fällen eine Ausnahme geworfen, zum Beispiel wenn die Nachricht leer ist.
Warum gibst du überhaupt undefined in den Parametern an?
Die explizite Angabe ist nur ein vereinfachtes Beispiel zum Verständnis. In Wirklichkeit kann dieser Wert von einer Funktion stammen, wenn Objekte zusammengeführt werden, und von vielem mehr. Hier ein Beispiel aus der PR:
await ctx.send("Hey` there!", {
keyboard: await getKeyboardToSend() //undefined | KeyboardBuilder - соответствие типов, но ошибка ругается API
});
Hier verwende ich es als Fallback-Typ, was bedeuten würde, dass Sie die Tastatur nicht anzeigen müssen
Die Tatsache, dass URLSearchParams undefined sammelt, ist wahrscheinlich flexibler und korrekter, aber weniger bequem.
Ich weiß nicht viel über vkapi und die Ressourcen dieser Bibliothek und kann nicht sagen, ob es ein Problem gibt, aber wenn es wirklich ein Problem mit unterschiedlichen Verhaltensweisen in einer Bibliothek gibt, sollte dies gelöst werden.
Ich denke, Sie können den Hauptteil der Anfrage direkt übergeben und er wird mit JSON.stringify in JSON konvertiert, das im Gegensatz zu URLSearchParams undefiniert abschneidet. Dies ist für Benutzer verwirrend.
Die Tatsache, dass URLSearchParams undefined sammelt, ist wahrscheinlich flexibler und korrekter, aber weniger bequem.
@talentumtuum stimmt nicht ganz zu, ich kann sogar ein Beispiel aus einer anderen sehr großen Lib geben.
Es gibt eine solche Prisma-Bibliothek (über die Sie Anfragen an die Datenbank stellen können). Und hier ist eines ihrer Beispiele:
const hisNotes = await prisma.userNote.findMany({
where: {
userName: "Dmitriy" // вернет записки только дмитрия
}
});
const allNotes = await prisma.userNote.findMany({
where: {
userName: undefined // не вернет записки пользователя "undefined"
}
});
// это равносильно
allNotes = await prisma.userNote.findMany({ });
upd: Nun, statt undefined wird in einigen Fällen eine Ausnahme geworfen, zum Beispiel wenn die Nachricht leer ist.
Ich stimme zu, stellen Sie sich vor, ein Bot spammt bei jedem Befehl "undefiniert". Bessere Ausnahme als stiller Unsinn xd
upd: Vielleicht sehen sie es zumindest in den Logs, aber sie werden es reparieren
Trotzdem denke ich, dass ein Fehler besser ist als ein problematischer Beitrag. In Tools wie Sentry ist es schwierig, herauszufinden, was kein Fehler ist. Major Version 4 zielte auf eine bessere Interaktion mit der Bibliothek ab und das explizite undefined
nicht.
Dies behebt auch nicht offensichtliches Verhalten zwischen URLSearamParams
und JSON.stringify()
, behoben unter https://github.com/negezor/vk-io/commit/1026d333a07ff50423100f331e74a8041e2f567d , veröffentlicht in 4.0.2