typescript - 如何编写回调可以在 TypeScript 中多个参数位置的函数?
问题描述
这是我到目前为止所拥有的,但是会引发错误bar[key]
(请参阅TypeScript Playground)。
我希望能够test
使用test("hello", { foo: "bar" }, () => {})
and调用test("hello", () => {})
。
type TestCallback = () => void
interface Bar {
[key: string]: string
}
const test = function(
foo: string,
bar?: Bar | TestCallback | null,
callback?: TestCallback
) {
if (typeof bar === "function") {
callback = bar
bar = null
}
if (bar && bar instanceof Object) {
Object.keys(bar).forEach(function(key) {
console.log(key, bar[key])
})
}
if (callback) {
callback()
}
}
解决方案
您的问题与您使用bar
函数参数的方式有关,默认情况下 TS 将参数视为 consts,但是当我们更改它们时,您通过设置bar = null
然后 TS 将其视为let
. 这种差异在下面可见:
{
// with let function declaration has not narrowed type
let a: string | number = 1;
if (typeof a === 'number') {
a // a is number yep
const f = () => {
a // a is not to be believed so it is string | number
}
}
}
{
// with const function declaration has narrowed type
const a: string | number = 1;
if (typeof a === 'number') {
a // a is number yep
const f = () => {
a // a is still number as it is const
}
}
}
因此,当我们const
在类型保护中使用函数声明时,会将此类型视为缩小范围,但let
不信任它。为什么?因为例如函数可以异步调用并且变量可以在之前更改,所以 TSlet
为了防止运行时错误而更具防御性。
这种情况适用于您的情况,通过重新分配参数bar
TS 将其切换到let
模式。我们可以通过删除重新分配来修复它。考虑:
const test = function(
foo: string,
bar?: Bar | TestCallback,
callback?: TestCallback
) {
if (bar && typeof bar !== 'function') {
Object.keys(bar).forEach((key) => {
console.log(key, bar[key]) // no error bar is Bar
})
}
if (callback) {
callback()
}
}
额外的想法
关于这种行为的一些想法以及它是否错误。它是主观的,我们需要了解很多因素,这也是编译需要快速的因素。TS 在这里选择直截了当的方法,你重新分配,TS 不太相信你的类型守卫持久性。在像您这样的某些情况下,这可能是一种负担,但仍有很多其他情况可以从这种安全性中受益。
推荐阅读
- angular - Angular 显示微调器请求 http
- python - 基于列的 Seaborn 条形图
- python - Two DataFrames, find index of second one where values of two columns match up from first
- floating-point - 是否可以通过在 VM 中运行程序来获得物理机之间的浮点确定性?
- javascript - 关于 LeetCode 77 (javascript) 的未定义错误
- c# - C# 从最后一个 JSON 对象迭代到第一个对象
- javascript - Electron webContents.send 并不总是有效
- orocommerce - OroCommerce:自定义订单视图页面上的按钮?
- reactjs - 无法通过 Ubuntu 服务器上的 LAN 在 iPad 上加载 React App 的本地部署
- python - 2 个不同寄存器的两个相同值 - minimummodbus