[英]Typescript: function return type is different when a parameter is undefined or its type is asserted
The code is simple but my use case is complex:代码很简单,但我的用例很复杂:
type MyFn = <B extends ['A']>(
param?: B
) => B extends undefined ? 'TYPE_1' : 'TYPE_2'
// so that
const test1 = myFn() // shall be type TYPE_1
const test2 = myFn(['A']) // shall be type TYPE_2
param
is undefined, then the type is 'TYPE_1'
else it is 'TYPE_2'
我希望如果param
未定义,则类型为'TYPE_1'
否则为'TYPE_2'
param
shall be dynamically typed, the goal is that the IDE autocompletes/validates values when writing the values inside the array param
应该是动态类型的,目标是 IDE 在将值写入数组时自动完成/验证值param
inside the function shall be at least (string[] | undefined) function 中的param
类型至少应为 (string[] | undefined)I tried a lot of different configurations without success: typescript playground我尝试了很多不同的配置都没有成功: typescript playground
The closest I could get actually was with this code:我实际上能得到的最接近的是这段代码:
type MyFn = <
T,
B extends ['A']
>(
param?: T | B
) => T extends string[] ? 'TYPE_2' : 'TYPE_1'
var a: MyFn3 = (param?) => (param ? 'TYPE_1' : 'TYPE_2') as any
const test1 = a() // IS type TYPE_1
const test2 = a(['A']) // IS be type TYPE_2
But the problem is that the inferred type inside of the function is any
because T
has no constraint type.但问题是 function 内部的推断类型是any
因为T
没有约束类型。 But at the moment we constraint the T
type, the condition in the return type returns always true.但是此时我们约束了T
类型,返回类型中的条件总是返回 true。
Is there any solutions to get around that problem?有什么解决方案可以解决这个问题吗?
The main goal behind such a type is to define an array of string as props address of an object, and return the value at that address.这种类型背后的主要目标是定义一个字符串数组作为 object 的 props 地址,并返回该地址的值。
Eg: ['level1', 'level2']
would return myObject.level1.level2
例如: ['level1', 'level2']
将返回myObject.level1.level2
Here is a simplified version of this real world use case 这是这个真实世界用例的简化版本
Your B
type is never undefined
, because ['A']
is never undefined.您的B
类型永远不会undefined
,因为['A']
永远不会未定义。 The compiler can effectively simplify your expression:编译器可以有效地简化你的表达式:
type MyFn = <B extends ['A']>(
param?: B
) => B extends undefined ? 'TYPE_1' : 'TYPE_2'
to到
type MyFn = <B extends ['A']>(
param?: B
) => false ? 'TYPE_1' : 'TYPE_2'
to到
type MyFn = <B extends ['A']>(
param?: B
) => 'TYPE_2'
The fact that param
is optionally B
has no effect on B
itself. param
是可选的B
这一事实对B
本身没有影响。
You need to broaden B
:你需要扩大B
:
type MyFn = <B extends ['A'] | undefined>(
which produces the correct result for产生正确的结果
const test1 = myFn(undefined) // TYPE_1
and then default to make it work when omitted:然后在省略时默认使其工作:
type MyFn = <B extends ['A'] | undefined = undefined>(
which produces the correct result for产生正确的结果
const test1 = myFn() // TYPE_1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.