嘿!
简而言之,使用明确指定值undefined
的参数调用任何API 都会导致它被转移到 VK。 下面是一个例子。
await ctx.send("it'll fail", {
keyboard: undefined
});
ctx
- 事件上下文message_new
不应传递值为undefined
参数,与省略它们完全相同。
VK-IO 将undefined
成字符串并提供给服务器。
| 包装 | 版本 |
| ---------------------------------- | -------- |
| vk-io
| 4.0.1
|
| node
| 12.17.0
|
| TypeScript
| 4.0.2
|
| yarn
| 1.22.4
|
不,等等,它有点不工作。 给你解释一下?
来吧,有什么小问题?
使用 URLSearchParams 发送参数
const params = {
message: 'hello',
keyboard: undefined
};
console.log(new URLSearchParams(params));
// Выведет: URLSearchParams { 'message' => 'hello', 'keyboard' => 'undefined' }
@isinkin是的,但我已经在 PR 中写过这是一个错误,因为 TypeScript 根本没有任何区别,没有指定参数或指定了值undefined
,但在运行时这已经导致 API 错误。 这是某种直接的陷阱。
@zardoy为什么这是一个错误?
const obj = {
key: undefined,
}
const properties = Object.getOwnPropertyNames(obj)
console.log(properties)
声明了属性,它的类型是未定义的,当转换为字符串时,得到字符串'undefined'。
ts 不能正常工作的事实已经适用于 ts,运行时通常在 v8 上,并且它只支持 javascript。
const obj = { key: undefined, } const properties = Object.getOwnPropertyNames(obj) console.log(properties)
没错,但为什么会发生这种转变? 毕竟,如果我们要显式传递这样内容的字符串,为什么不显式地将字符串作为参数传递呢?
vk.api.messages.send({
message: "undefined" // - так ок
});
也许你是对的,这不是一个错误,而只是一个陷阱,因为当你明确指定undefined
时 ts 不会引发编译错误。 但是,我在 PR 中的建议是,当我们完全省略参数并指定undefined
将是相同的,因为并非总是如此
Sori,我关闭了,我现在将添加。
@zardoy我明白你的意思。
当然你写的东西像
let someVariable;
const query = {
key: someVariable,
}
send(query)
我认为这个问题出在用户方面,您需要以不同的方式编写,并且使用此 pr 您会破坏向后兼容性。
我认为这个问题出在用户方面,您需要以不同的方式编写,并且使用此 pr 您会破坏向后兼容性。
我同意。
看看狗被埋在哪里(一个更说明性的例子):
我不能那样拼写
我已经可以做到了
ts 会发誓,尽管请求实际上是一样的。 对用户来说只是一个陷阱
@zardoy所以如果你不想传递这个参数就不要写任何东西,它会按照你想要的方式工作
vk.api.messages.send()
存在相当不匹配的行为, JSON.stringify()
undefined
将被遗漏。 而URLSearchParams
将所有内容都引导到一个字符串。 这不会破坏向后兼容性,因为检查的是undefined
,而不是"undefined"
。
但是现在我们将以undefined
的形式在聊天中丢失有趣的消息 :)
@negezor关于我的意思是这样的消息,有人可能在他们想要打印这样的文本时使用了未定义的类型)
upd:好吧,不是未定义,而是在某些情况下会抛出异常,例如,当消息为空时。
你为什么在参数中指定 undefined ?
显式指示是一个简化示例,仅用于理解目的。 实际上,这个值可以来自一个函数,当对象被合并时,也可以来自很多其他地方。 这是 PR 的一个例子:
await ctx.send("Hey` there!", {
keyboard: await getKeyboardToSend() //undefined | KeyboardBuilder - соответствие типов, но ошибка ругается API
});
在这里我将它用作后备类型,这意味着您不需要显示键盘
URLSearchParams 收集未定义的事实可能更灵活和正确,但不太方便。
我对vkapi和这个lib的资源不太了解,我不能说是否有问题,但如果一个库中确实存在不同行为的问题,那么应该解决这个问题。
我猜您可以直接传递请求的主体,然后使用 JSON.stringify 将其转换为 JSON,与 URLSearchParams 不同,它会截断 undefined,这会让用户感到困惑。
URLSearchParams 收集未定义的事实可能更灵活和正确,但不太方便。
@talentumtuum不太同意,我什至可以举一个来自另一个非常大的库的例子。
有这样一个棱镜库(通过它你可以对数据库进行查询)。 这是他们的一个例子:
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:好吧,不是未定义,而是在某些情况下会抛出异常,例如,当消息为空时。
我同意,想象一下,如果机器人垃圾邮件在任何命令上“未定义”。 比沉默的废话更好的例外xd
upd:也许他们至少会在日志中看到它,但他们会修复它
不过,我认为一个错误比一个有问题的帖子更好。 在像Sentry这样的工具中undefined
不是。
这也修复了URLSearamParams
和JSON.stringify()
之间的不明显行为,固定在https://github.com/negezor/vk-io/commit/1026d333a07ff50423100f331e74a8041e2f567d ,发布于4.0.2