【问题标题】:Disallow call with any禁止与任何人通话
【发布时间】:2020-03-29 03:12:44
【问题描述】:

考虑以下函数重载:

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

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

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


完整的demo code:

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


    【解决方案1】:

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


    话虽如此,您可以使用新的conditional types 功能为any 构建检测器,然后可以使用它来禁止any 变量。

    这是检测器:

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

    不满足类型约束0 extends 10 不能分配给1),所以0 extends (1 &amp; T) 也不可能满足,因为(1 &amp; T) 应该比@987654335 更窄@。但是,当Tany 时,它会将0 extends (1 &amp; any) 减少为0 extends any,这是满足的。这是因为any 是有意为unsound 并充当几乎 其他所有类型的超类型和子类型。因此,IfAny&lt;T, Y, N&gt; 检查T 是否为any。如果是,则返回Y。如果不是,则返回T。让我们看看它的工作原理:

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

    回想一下,我说过any 匹配几乎所有其他类型。唯一匹配any的类型是never

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

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

    function f(key: undefined): void;
    

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

    我们已将key 设为泛型类型K,它被限制为IfAny&lt;K, never, undefined&gt;。如果K 不是any,那么那个约束就是undefined,所以K 只能是undefined。如果Kany,那么那个约束就变成never,由于any不匹配never,它就不能满足这个约束。

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

    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
    

    这就是你想要的。

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

    【讨论】:

    • 谢谢!很好的解决方案!但您必须注意,它仅适用于启用strictNullChecks。否则 f(undefined) 也会产生错误。
    • 啊,是的,我从来没有试过关闭strictNullChecks
    • 如何更改此解决方案以使其与通用参数一起使用? stackoverflow.com/q/55577863/4928642 // 抄送 @TitianCernicova-Dragomir
    • @Qwertiy 我同意 jcalz 那边的回答
    猜你喜欢
    • 2013-09-23
    • 2018-11-12
    • 2018-04-30
    • 2021-07-25
    • 1970-01-01
    • 2023-03-15
    • 2021-01-03
    • 1970-01-01
    • 2021-09-16
    相关资源
    最近更新 更多