Typescript 类型缩小后,类型不可分配给自身
给定以下代码Typescript 类型缩小后,类型不可分配给自身,typescript,union-types,typeguards,Typescript,Union Types,Typeguards,给定以下代码 type Test = string | boolean | string[] | boolean[] function test (param: Test) { if (!_.isArray(param)) { param = [param] } return param } 我收到以下错误 (参数)param:string | boolean 类型“string | boolean”不可分配给类型“boolean”。 类型“string”不可分配给类型
type Test = string | boolean | string[] | boolean[]
function test (param: Test) {
if (!_.isArray(param)) {
param = [param]
}
return param
}
我收到以下错误
(参数)param:string | boolean
类型“string | boolean”不可分配给类型“boolean”。
类型“string”不可分配给类型“boolean”。ts(2322)
解决办法是
type Test = string | boolean | (string | boolean)[]
但是我不理解我的解决方案这里的问题是,一旦你确定
param
不是一个数组,它的类型就被限制为string | boolean
,当你取一个该类型的值并把它放在数组文本类型中时,脚本就会推断出类型是[string | boolean]
,这与string不同[]| boolean[]
。如果您选择了每种可能的类型,然后在单独的分支中使用了相同的代码行,那么:
type Test=string | boolean | string[]| boolean[]
功能测试(参数:测试){
if(typeof param=='string'){
param=[param];
}else if(typeof param=='boolean'){
param=[param];
}
返回参数
}
如果不清楚这些类型之间的区别,则其中一种(
(string | boolean)[
)可以是包含字符串和布尔值混合的数组,其中另一种(string[]| boolean[]
)是仅包含字符串的数组,或仅包含布尔值的数组。不幸的是,在这种情况下,Typescript不够聪明,无法实现数组[param]
本质上是同质的,因为它只有一个元素。这里的问题是,一旦确定param
不是数组,它的类型就被约束为string | boolean
,当您获取该类型的值并将其放入数组文字类型脚本就会推断出该类型为[string | boolean]
与string[]| boolean[]
不同。如果您检查了每种可能的类型,然后在单独的分支中使用相同的代码行,则可以:
type Test=string | boolean | string[]| boolean[]
功能测试(参数:测试){
if(typeof param=='string'){
param=[param];
}else if(typeof param=='boolean'){
param=[param];
}
返回参数
}
如果不清楚这些类型之间的区别,则其中一种(
(string | boolean)[
)可以是包含字符串和布尔值混合的数组,其中另一种(string[]| boolean[]
)是一个只包含字符串的数组,或者是一个只包含布尔值的数组。不幸的是,在这种情况下,Typescript不够聪明,无法意识到数组[param]
本质上是同质的,因为它只有一个元素。请考虑以下解决方案:
type Test=string | boolean | string[]| boolean[]
常量测试=(参数:测试)=>Array.isArray(参数)?参数:[param]
你不需要变异任何东西。我相信你甚至不需要在这里使用lodash
我的意见是:
对我来说,在条件语句中没有否定运算符时,它可读性很强
更新
谢谢保罗·惠勒纠正我的错误
这里有我的缩小类型的解决方案
type Test=string | boolean | string[]| boolean[]
常量strOrBool=(val:unknown):val是字符串|布尔=>
typeof val=='string'| | typeof val==='boolean'
功能测试(参数:T):[T]
功能测试(参数:T):[T]
功能测试(参数:[…U]):U
功能测试(参数:[…U]):U
功能测试(参数:T){
返回strOrBool(参数)?[参数]:参数
}
常数结果=测试(真)/[真]
const result2=test('hello')/[“hello”]
const result3=test(['hello'])/[“hello”]
const result4=测试([true])/[true]
顺便说一句,typescript不能很好地处理变异值,它可能会导致错误考虑一下这个解决方案:
type Test=string | boolean | string[]| boolean[]
常量测试=(参数:测试)=>Array.isArray(参数)?参数:[param]
你不需要变异任何东西。我相信你甚至不需要在这里使用lodash
我的意见是:
对我来说,在条件语句中没有否定运算符时,它可读性很强
更新
谢谢保罗·惠勒纠正我的错误
这里有我的缩小类型的解决方案
type Test=string | boolean | string[]| boolean[]
常量strOrBool=(val:unknown):val是字符串|布尔=>
typeof val=='string'| | typeof val==='boolean'
功能测试(参数:T):[T]
功能测试(参数:T):[T]
功能测试(参数:[…U]):U
功能测试(参数:[…U]):U
功能测试(参数:T){
返回strOrBool(参数)?[参数]:参数
}
常数结果=测试(真)/[真]
const result2=test('hello')/[“hello”]
const result3=test(['hello'])/[“hello”]
const result4=测试([true])/[true]
顺便说一句,typescript不能很好地处理变异值,它可能会导致错误示例中的
test
函数实际上没有所需的类型签名。所需的签名是test->test
,但您的函数有签名test->(string | boolean)[]
。您可以通过声明let example:Test;
来验证这一点,然后尝试将Test
函数的结果分配给它:example=Test('foo');
。示例中的test
函数实际上没有所需的类型签名。所需的签名是test->test
,但您的函数有签名test->(字符串|布尔值)[]
。您可以通过声明let example:Test;
来验证这一点,然后尝试将Test
函数的结果分配给它:example=Test('foo');
。