如果指定了泛型,则不允许任何调用 [英] Disallow call with any if generic is specified

查看:46
本文介绍了如果指定了泛型,则不允许任何调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试应用此解决方案禁止调用第二种类型等于 any的泛型函数.

I've tried to apply this solution to disallow call of generic function with second type equal to any.

以下构造工作直到明确指定第一个通用参数为止:

Following construction works until the first generic parameter is explicitely specified:

 declare function f<V = any, A extends ISmth = ISmth>(a: IfAny<A, never, A>): V;

如果我需要 V 作为第一个参数并且是可选的(它是返回类型并且不能推断-应该以显式方式指定或任意指定),我该如何解决代码吗?

In case that I need V to be first parameter and to be optional (it's return type and can't be inferred - it should iether be specified explicitely or be any), how can I fix the code?

我尝试更改默认值,但是它会中断任何使用显式第一种类型的呼叫:

I've tried to change default value, but it breakes any calls with explicit first type:

declare function g<V = any, A extends ISmth = any>(a: IfAny<A, never, A>): V;

完整代码:

interface ISmth { x: number; }

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

declare function f<V = any, A extends ISmth = ISmth>(a: IfAny<A, never, A>): V;
declare function g<V = any, A extends ISmth = any>(a: IfAny<A, never, A>): V;

declare var x: ISmth, y: any;

f(x); // Fine
f(y); // Fine: Argument of type 'any' is not assignable to parameter of type 'never'.

f<string>(x); // Fine
f<string>(y); // BAD: Should be an error, but compiles

g(x); // Fine
g(y); // Fine: Argument of type 'any' is not assignable to parameter of type 'never'.

g<string>(x); // BAD: Should NOT be an error
g<string>(y); // Fine: Argument of type 'any' is not assignable to parameter of type 'never'.

推荐答案

当前没有部分类型类型推断中的参数推断,因此这对您不起作用.解决方法是制作一个 curried 函数,在该函数中您手动指定一个类型参数并返回其类型的函数参数推断:

There's currently no partial type argument inference in TypeScript, so this won't work for you. Workarounds are to make a curried function where you manually specify one type parameter and return a function whose type parameter is inferred:

declare const fCurry: <V = any>() => 
  <A extends ISmth = ISmth>(a: IfAny<A, never, A>) => V;
fCurry()(x); // no error
fCurry()(y); // error
fCurry<string>()(x); // no error
fCurry<string>()(y); // error

或者您创建了一个函数,该函数为要手动指定的类型参数使用伪参数...在运行时可以为 null ,但是您可以使用类型断言来让编译器知道输入您的意思:

Or you make a function that takes a dummy argument for the type parameter you wish to manually specify... it can be null at runtime but you use a type assertion to let the compiler know what type you mean:

declare function fDummy<V = any, A extends ISmth = ISmth>(
  a: IfAny<A, never, A>, 
  dummy?: V
): V;
fDummy(x); // no error
fDummy(y); // error
fDummy(x, null! as string); // no error
fDummy(y, null! as string); // error

这两种方法都不完美,但是它们具有所需的行为.希望能有所帮助.祝你好运!

Neither way is perfect, but they have the desired behavior. Hope that helps. Good luck!

这篇关于如果指定了泛型,则不允许任何调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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