我如何基于具有一个参数是两种类型的并集的函数来适当地推断返回类型?
我已经尝试使用条件类型进行以下操作,但它不起作用(有关打字稿错误,请参见内联注释):
type Status = 'statusType'
type GoalActivity = 'goalActivityType'
type Argument = { type: 'status'; status: Status | null } | { type: 'goalActivity'; goalActivity: GoalActivity | null }
const handleReaction = (arg: Argument): Argument extends { type: "status" } ? Status : GoalActivity => {
if (arg.type === 'status') {
return 'statusType' // Type '"statusType"' is not assignable to type '"goalActivityType"'.
} else {
return 'goalActivityType'
}
}
我还尝试过使用箭头函数的函数重载形式进行以下操作(如此处所述),但这也会导致TypeScript错误,并且还会使用“ any”,这会丢失函数定义中的大多数键入好处:
type Status = 'statusType'
type GoalActivity = 'goalActivityType'
type HandleReaction = {
(arg: { type: 'status'; status: Status | null }): Status
(arg: { type: 'goalActivity'; goalActivity: GoalActivity | null }): GoalActivity
}
const handleReaction: HandleReaction = (arg: any) => { // Type '"goalActivityType"' is not assignable to type '"statusType"'.
if (arg.type === 'status') {
return 'statusType'
} else {
return 'goalActivityType'
}
}
这个问题与此类似,但是区别在于功能参数是一个对象。
第一件事是您没有为参数使用泛型,因为泛型typescript
永远不会根据您的输入来推断正确的类型(您可以想象泛型是参数,tsc
需要它根据输入来计算结果)。
简而言之,
const handleReaction = (arg: Argument): Argument extends { type: "status" } ? Status : GoalActivity => { // ... }
将始终Status | GoalActivity
以返回类型返回。
当然,您必须在此处使用泛型类型作为参数。我将用内联说明将您的代码分开:
type Status = 'statusType'
type GoalActivity = 'goalActivityType'
type StatusObj = { type: 'status'; status: Status | null };
type GoalActivityObj = { type: 'goalActivity'; goalActivity: GoalActivity | null }
type Argument = StatusObj | GoalActivityObj;
// Define returned type based on a input argument `T`
type ReturnType<T> = T extends StatusObj ? Status : GoalActivity;
// Generic type should be used here
const handleReaction = <T extends Argument>(arg: T): ReturnType<T> => {
if (arg.type === 'status') {
// Q: Why do we have to cast here?
// A: Any returned type can't assign to statement of `type ReturnType<T> ...`
// but luckily `tsc` still allows us to cast back since they are all string literal
return 'statusType' as ReturnType<T>;
} else {
return 'goalActivityType' as ReturnType<T>;
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句