禁止与任何人通话 [英] Disallow call with any

查看:38
本文介绍了禁止与任何人通话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下函数重载:

function f(key: undefined);
function f(key: string | undefined, value: object | undefined);

我想使用单个显式未定义 f(undefined) 进行符合条件的调用,但对于所有其他情况需要两个参数.上面的重载工作正常,直到我传递一个类型为 any 的变量 - 似乎 any 可以转换为 undefined (是的,这似乎合乎逻辑因为它是任何).

I want to make eligible calls with single explicit undefined f(undefined), but require two arguments for all other cases. And overloads above work fine, until I pass a variable with type any - seems like any can be casted to undefined (yes, it seems logical as it is any).

如何禁止使用单个 any 参数进行调用?

How can I disallow call with single any argumnent?

完整 演示代码:

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);

推荐答案

TypeScript 真的不想禁止 any 匹配类型,因为这是 any 的全部意义代码>.您可能想要重新考虑任何依赖于拒绝 any 的代码,所以请谨慎行事.

TypeScript really doesn't want to disallow any from matching a type, since that's the whole point of any. You might want to rethink any code which relies on rejecting any, so tread lightly.

话虽如此,您可以使用新的 条件类型 功能,为any 构建检测器,然后可用于禁止any 变量.

That being said, you can use the new conditional types feature to build a detector for any which can then be used to disallow an any variable.

这是检测器:

type IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N; 

类型约束0 extends 1不满足(0不可赋值给1),所以应该是不可能的>0 extends (1 & T) 也可以满足,因为 (1 & T) 应该比 1 更窄.然而,当Tany时,它会将0 extends (1 & any)减少到0 extends any,这是满意的.那是因为 any 故意不健全并且作为几乎所有其他类型的超类型和子类型.因此,IfAny 检查 T 是否为 any.如果是,则返回 Y.如果不是,则返回 T.让我们看看它是否有效:

The type constraint 0 extends 1 is not satisfied (0 is not assignable to 1), so it should be impossible for 0 extends (1 & T) to be satisfied either, since (1 & T) should be even narrower than 1. However, when T is any, it reduces 0 extends (1 & any) to 0 extends any, which is satisfied. That's because any is intentionally unsound and acts as both a supertype and subtype of almost every other type. Therefore, IfAny<T, Y, N> checks if T is any. If so, it returns Y. If not, it returns T. Let's see it work:

type IsAny<T> = IfAny<T, true, false>
const yes: IsAny<any> = true;
const no: IsAny<string> = false;

<小时>

记得我说过 any 匹配几乎所有其他类型.唯一匹配any的类型是never:


Recall that I said any matches almost every other type. The only type that doesn't match any is never:

declare const any: any;
const never: never = any; // error, any is not assignable to never

我们也需要这个事实,以便拒绝任何参数.让我们将 f() 的第一个签名从

We need that fact too, in order to reject any parameters. Let's change the first signature of f() from

function f(key: undefined): void;

function f<K extends IfAny<K, never, undefined>>(key: K): void;

我们使 key 成为一个通用类型 K,它被限制为 IfAny.如果 K 不是 any,那么约束就是 undefined,所以 K 只能是 undefined 根据需要.如果 K is any,则该约束变为 never,并且由于 any不匹配never,就会不满足约束条件.

We've made the key a generic type K that is constrained to IfAny<K, never, undefined>. If K is not any, then that constraint is just undefined, so K can only be undefined as desired. If K is any, then that constraint becomes never, and since any does not match never, it will fail to meet the constraint.

当我们使用上述签名时,您会看到以下行为:

When we use the above signature, you see the following behavior:

f(undefined); // still works
f(""); // still error, "" is not assignable to undefined

declare var x: any;
f(x); // now error, any is not assignable to never

这就是你想要的.

希望有所帮助;祝你好运!

Hope that helps; good luck!

这篇关于禁止与任何人通话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆