Typescript 基于参数区分返回类型

Typescript 基于参数区分返回类型,typescript,Typescript,我试图键入一个函数,该函数接受字符串或字符串[],并分别返回bool或bool[]。我尝试过使用泛型类型和重载,但两者似乎都会引发某种错误: //通用方式 函数genericWay(val:T):T扩展字符串?布尔值:布尔值[]{ if(typeof val=='string'){ return true//Type'true'不可分配给Type'T extends string?boolean:boolean[] } return[true]//类型“true[]”不可分配给类型“T exte

我试图键入一个函数,该函数接受字符串或字符串[],并分别返回bool或bool[]。我尝试过使用泛型类型和重载,但两者似乎都会引发某种错误:

//通用方式
函数genericWay(val:T):T扩展字符串?布尔值:布尔值[]{
if(typeof val=='string'){
return true//Type'true'不可分配给Type'T extends string?boolean:boolean[]
}
return[true]//类型“true[]”不可分配给类型“T extends string”?布尔值:布尔值[]
}
常量a1=重载方式('bbb')
常量a2=一般通道(['bbb'])
const a3=genericWay(5333)//应该抛出错误
//过载方式
函数重载方式(val:string[]):boolean[];//此重载签名与其实现签名不兼容。
函数重载方式(val:string):布尔{
if(typeof val=='string'){
返回真值
}
return[true]//类型“boolean[]”不能分配给类型“boolean”。
}
常量b1=重载方式('bbb')
const b2=overloadWay(['bbb']))
const b3=overloadWay(5333)//应该抛出错误

  • 从第一个例子来看,我的返回类型似乎不正确
  • 对于重载方式,出于某种原因,它没有在类型检查时进行区分,以区分这两种输入类型

  • 我已经对泛型方法应用了一些更改,以拥有一个单独的泛型类型,并使用
    断言返回值类型为
    ,检查

    type genType=T扩展字符串?布尔值:布尔值[];
    函数genericWay(val:T):genType{
    if(typeof val=='string'){
    返回true作为genType
    }
    返回[true]作为genType
    }
    常数a1=一般通道('bbb')
    常量a2=一般通道(['bbb'])
    const a3=genericWay(5333)//应该抛出错误
    
    由于另一个答案已经提供了如何以通用方式修复警告,这需要显式类型转换,因此下面介绍如何使用函数重载来实现相同的目标

    您的重载方式定义不正确。您需要在函数之前指定所有重载,实现函数应该在其签名中包含所有可能的输入和输出。在实现过程中,您可以使用
    任何
    ,但我认为无论在什么地方,只要可以避免,这都是不可取的

    这是超负荷方式

    //重载方式
    函数重载方式(val:string[]):boolean[];
    函数重载方式(val:string):布尔值;
    函数重载方式(val:string | string[]):boolean | boolean[]{
    if(typeof val=='string'){
    返回真值
    }
    返回[真]
    }
    //b1是布尔值
    常量b1=重载方式('bbb')
    //b2是布尔值[]
    const b2=overloadWay(['bbb']))
    //显示错误
    常数b3=过载方式(5333)
    

    这是一个很好的问题,但是如果您只是让函数始终接受字符串[]并始终返回布尔[],那么即使不知道答案,您也不能完成同样的任务吗?如果只想传入一个字符串,只需传入一个长度为1的字符串[],并且字符串位于第一个也是唯一的元素中。然后,如果返回的数组中没有其他元素,您还可以检查返回值的长度,并将长度为1的bool[]转换为bool?我可以,但在这一点上,我也很好奇为什么这个实现不起作用,以及我做错了什么(出于学习目的)。这更有意义-没有意识到需要在函数之前指定所有重载。
    type genType<T> = T extends string ? boolean : boolean[];
    
    function genericWay<T extends string | string[]>(val: T): genType<T> {
        if (typeof val === 'string'){
            return true as genType<T>
        }
        return [true] as genType<T>
    }
    
    const a1 = genericWay('bbb')
    const a2 = genericWay(['bbb'])
    const a3 = genericWay(5333) // should throw error