禁止与任何人通话

Qwe*_*tiy 4 typescript

考虑以下函数重载:

function f(key: undefined);
function f(key: string | undefined, value: object | undefined);
Run Code Online (Sandbox Code Playgroud)

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

我如何禁止与单个anyargumnent通话?


完整的演示代码:

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);
Run Code Online (Sandbox Code Playgroud)

jca*_*alz 12

TypeScript真的不想禁止any匹配一个类型,因为这是整个点any.您可能想要重新考虑任何依赖拒绝的代码any,因此请谨慎行事.


话虽这么说,您可以使用新的条件类型功能来构建一个检测器,any然后可以使用它来禁止any变量.

这是探测器:

type IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N; 
Run Code Online (Sandbox Code Playgroud)

类型约束0 extends 1不满足(0不可分配1),因此也不可能0 extends (1 & T)满足,因为(1 & T)应该甚至更窄1.但是,如果Tany,它减少0 extends (1 & any)0 extends any,这是满意的.这是因为any故意不健全,并且几乎是所有其他类型的超类型和子类型.因此,IfAny<T, Y, N>检查是否Tany.如果是,则返回Y.如果没有,它返回T.让我们看看它是否有效:

type IsAny<T> = IfAny<T, true, false>
const yes: IsAny<any> = true;
const no: IsAny<string> = false;
Run Code Online (Sandbox Code Playgroud)

回想一下,我说any匹配几乎所有其他类型.唯一匹配的类型anynever:

declare const any: any;
const never: never = any; // error, any is not assignable to never
Run Code Online (Sandbox Code Playgroud)

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

function f(key: undefined): void;
Run Code Online (Sandbox Code Playgroud)

function f<K extends IfAny<K, never, undefined>>(key: K): void;
Run Code Online (Sandbox Code Playgroud)

我们制作了key一个K受限制的泛型类型IfAny<K, never, undefined>.如果K不是any,那么该约束只是undefined,所以K只能undefined按照需要.如果K any,那么该约束变为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
Run Code Online (Sandbox Code Playgroud)

这就是你想要的.

希望有所帮助; 祝好运!

  • 谢谢你!很好的解决方案!但您必须注意,它仅适用于启用“strictNullChecks”的情况。否则“f(undefined)”也会产生错误。 (2认同)