请考虑以下函数重载:
function f(key: undefined);
function f(key: string | undefined, value: object | undefined);
我想用一个明确的未定义的f(undefined)
进行合格的调用,但是对于所有其他情况需要两个参数。上面的重载工作正常,直到我传递了一个any
类型的变量-看起来any
可以强制转换为undefined
(是的,看起来像是任何逻辑)。
如何禁止使用单个any
参数的调用?
完整演示代码:
function f(key: undefined);
function f(key: string | undefined, value: object | undefined);
function f(key: string | undefined, value?: object | undefined) {
console.log(key, value);
}
// No errors - RIGHT
f(undefined);
f("", {});
f("", undefined);
f(undefined, undefined);
f(undefined, {});
// Errors - RIGHT
f("");
// No errors - WRONG
declare var x: any;
f(x);
1条答案
按热度按时间1hdlvixo1#
TypeScript确实不想禁止
any
匹配类型,因为这是any
的全部意义所在。您可能需要重新考虑依赖于拒绝any
的任何代码,所以要谨慎行事。也就是说,您可以使用条件类型为
any
构建一个检测器,然后使用该检测器来禁止any
变量。这是探测器:
不满足类型约束
0 extends 1
(0
不能赋值给1
),所以0 extends (1 & T)
应该也不可能满足,因为(1 & T)
应该比1
还要窄,但是当T
为any
时,它将0 extends (1 & any)
简化为0 extends any
,这是满足的。这是因为any
是故意不合理的,并且充当几乎所有其他类型的超类型和子类型。因此,IfAny<T, Y, N>
检查T
是否是any
。如果是,它返回Y
。如果不是,它返回N
。让我们看看它是如何工作的:回想一下,我说过
any
几乎匹配所有其他类型,唯一不匹配any
的类型是never
:为了拒绝
any
参数,我们也需要这个事实。让我们将f()
的第一个签名从到
我们已经将
key
设置为泛型类型K
,并将其约束为IfAny<K, never, undefined>
。如果K
不是any
,则该约束只是undefined
,因此K
只能是所需的undefined
。如果K
* 是 *any
,则该约束变为never
。并且由于x1M37N1x不匹配x1M38N1x,因此它将不能满足约束。当我们使用上面的签名时,您会看到以下行为:
这正是你想要的
Playground代码链接