TypeScript:条件类型并使用布尔参数来控制返回类型

Posted

技术标签:

【中文标题】TypeScript:条件类型并使用布尔参数来控制返回类型【英文标题】:TypeScript: conditional types and using a boolean parameter to control the return type 【发布时间】:2018-12-28 03:37:05 【问题描述】:

如何在不使用重载签名的情况下改用条件类型来重写它?

function foo(returnString: true): string;
function foo(returnString: false): number;
function foo(returnString: boolean) 
  return returnString ? String(Math.random()) : Math.random();

我尝试了下面的代码,但是没有as any就无法编译:

function foo<T extends boolean>(returnString: T): T extends true ? string : number 
  return (returnString ? String(Math.random()) : Math.random()) as any;

我怎样才能摆脱as any

错误信息超级无用:

Type 'string | number' is not assignable to type 'T extends true ? string : number'.
  Type 'string' is not assignable to type 'T extends true ? string : number'.

【问题讨论】:

看起来这是一个known issue,他们在那个问题中提到any 强制转换或重载是当前的解决方法。此外,在他们的June Design Meeting Notes 中,他们提到:今天,一个类型不能分配给一个条件类型,除非它是另一个条件类型。,所以他们似乎意识到了这一点,并且可能会进行修复未来。 @CRice 谢谢!在问我的问题之前,我花了很长时间试图找到一个相应的问题,但它隐藏得太好了。 【参考方案1】:

我不确定为什么编译器不能按原样接受这个(对 TypeScript 不是很熟悉),但您可以这样做:

function foo<T extends boolean>(returnString: T): T extends true ? string : number;
function foo<T extends boolean>(returnString: T): string | number 
  return returnString ? String(Math.random()) : Math.random();

基本上,您将声明(公共签名)和实现分开,为声明提供更准确的签名,为实现提供更广泛的签名。

【讨论】:

这行得通,但我认为条件类型可以让我们在这种情况下完全摆脱声明签名。 我的真实签名当然比示例复杂。保留两份感觉不对。【参考方案2】:

我认为你应该这样写你的函数:

export class MyService 

    request(param: false): string; // must a defination;

    request(param: true): number;

    request(param: any): string | number 
        return null;
    


借自https://github.com/angular/angular/blob/master/packages/common/http/src/client.ts

使用 typescript 2.8,你可以这样写 func:

function fun<T extends true | false>(t: T): T extends true ? string : number 
    return null;

【讨论】:

您是否尝试编译此代码?它似乎无法工作。如果是,请添加编译的示例。 我明白了。这正是 OP 明确声明为不可取的。 对不起,这是我的错,这是typescript 2.8的一个特性,你可以这样写:function fun(t:T):T扩展真?字符串:数字 返回空值; 我已经在你的函数中添加了 return 语句(就像有问题的那样) - 它似乎无法区分 truefalseT extends boolean 独立于价值。

以上是关于TypeScript:条件类型并使用布尔参数来控制返回类型的主要内容,如果未能解决你的问题,请参考以下文章

5种在TypeScript中使用的类型保护

TypeScript 分布式条件类型 - 附加类型参数约束

TypeScript 基础类型

5种在TypeScript中使用的类型保护

TIJ读书笔记02-控制执行流程

布尔表达式与条件判断