流式细化混合功能
Flow type refine mixed to function
我正在使用 koa,它的中间件 props 类型是混合的,所以我试图按照下面的方式做一些事情,但我收到一个错误 Cannot call `ctx.render` because mixed [1] is not a function.Flow(not-a-function)
app.use(async (ctx, next) => {
// some other code above it
await ctx.render('index');
});
我的问题是,进行类型优化的正确方法是什么,这是一个函数,然后允许我调用它?
您可以将其细化为一个函数,但调用它是另一回事。
app.use(async (ctx, next) => {
if (typeof ctx.render === 'function') {
// Now we know that `ctx.render` is a function.
}
});
Flow 实际上有一个特例,称为“未知函数”。我们知道 ctx.render
是一个函数,但我们对它的参数或 return 类型一无所知,因此除了传递它之外我们无法安全地对它做任何事情。如果我们不知道 ctx.render
接受 number
,我们如何安全地调用 ctx.render(1)
?
更重要的是,我们无法知道任何关于它的信息。 JavaScript 没有提供反射机制,我们可以查询有关此函数的足够信息以便能够安全地调用它。我们唯一能找到的是静态元数 (ctx.render.length
),但这本身并不可靠或不充分。
如果我们有更多信息,比如如果这是一个联合类型而不是 mixed
,那么我们可以使用类型优化来做我们想做的事情:
(arg: boolean | (number => void)) => {
if (typeof arg === 'function') {
arg(1); // safe because if this is a function, we know it takes a number
}
};
这种情况下最合理的解决办法是通过any
打字。假设我们知道我们应该只接收一种类型的 render
函数,那么我们只是强行将它强制转换为该类型,并带有人们期望的所有警告:
// I don't know what the type of your render function is, but you would put it
// here:
type RenderFunction = string => void;
app.use(async (ctx, next) => {
// some other code above it
if (typeof ctx.render === 'function') {
// DANGER: We make a hard assumption here that the render function is
// always of this specific type. If it is ever of any other type then
// behavior is undefined!
await ((ctx.render: any): RenderFunction)('index');
}
});
在我看来,koa libdef 可能还可以改进。
我正在使用 koa,它的中间件 props 类型是混合的,所以我试图按照下面的方式做一些事情,但我收到一个错误 Cannot call `ctx.render` because mixed [1] is not a function.Flow(not-a-function)
app.use(async (ctx, next) => {
// some other code above it
await ctx.render('index');
});
我的问题是,进行类型优化的正确方法是什么,这是一个函数,然后允许我调用它?
您可以将其细化为一个函数,但调用它是另一回事。
app.use(async (ctx, next) => {
if (typeof ctx.render === 'function') {
// Now we know that `ctx.render` is a function.
}
});
Flow 实际上有一个特例,称为“未知函数”。我们知道 ctx.render
是一个函数,但我们对它的参数或 return 类型一无所知,因此除了传递它之外我们无法安全地对它做任何事情。如果我们不知道 ctx.render
接受 number
,我们如何安全地调用 ctx.render(1)
?
更重要的是,我们无法知道任何关于它的信息。 JavaScript 没有提供反射机制,我们可以查询有关此函数的足够信息以便能够安全地调用它。我们唯一能找到的是静态元数 (ctx.render.length
),但这本身并不可靠或不充分。
如果我们有更多信息,比如如果这是一个联合类型而不是 mixed
,那么我们可以使用类型优化来做我们想做的事情:
(arg: boolean | (number => void)) => {
if (typeof arg === 'function') {
arg(1); // safe because if this is a function, we know it takes a number
}
};
这种情况下最合理的解决办法是通过any
打字。假设我们知道我们应该只接收一种类型的 render
函数,那么我们只是强行将它强制转换为该类型,并带有人们期望的所有警告:
// I don't know what the type of your render function is, but you would put it
// here:
type RenderFunction = string => void;
app.use(async (ctx, next) => {
// some other code above it
if (typeof ctx.render === 'function') {
// DANGER: We make a hard assumption here that the render function is
// always of this specific type. If it is ever of any other type then
// behavior is undefined!
await ((ctx.render: any): RenderFunction)('index');
}
});
在我看来,koa libdef 可能还可以改进。