Typescript返回类型取决于对象参数

罗伯特·库珀

我如何基于具有一个参数是两种类型的并集的函数来适当地推断返回类型?

我已经尝试使用条件类型进行以下操作,但它不起作用(有关打字稿错误,请参见内联注释):

TypeScript游乐场

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”,这会丢失函数定义中的大多数键入好处:

TypeScript游乐场

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'
    }
}

这个问题与类似,但是区别在于功能参数是一个对象。

tmhao2005

问题

第一件事是您没有为参数使用泛型,因为泛型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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Typescript返回类型取决于参数

Typescript函数的返回类型取决于参数的数量或类型

Typescript 对象属性取决于类型

如何定义返回类型取决于其参数值的函数?

GraphQL-返回取决于参数的计算类型

打字稿:声明返回类型取决于参数值?

非类型参数取决于其后的参数

值类型取决于键类型的对象

可变参数模板函数,其中返回类型取决于模板参数列表

如果返回类型取决于参数,为什么/如何使参数可选?

返回类型取决于参数类型(例如Await.ready())不能按预期工作

如何键入提示返回类型取决于参数输入类型的函数?

如何返回动态类型取决于函数中的参数类型

泛型类型参数取决于自己

类型定义应取决于模板参数

返回值取决于方法参数

TypeScript:接口,取决于(递归)属性的类型

sizeof(pointer)是否取决于对象类型?

交换链接类型取决于模型对象

取消绑定取决于对象类型

Scala:如何使函数的返回类型通用并取决于运行时参数?

泛型理解返回类型取决于输入参数的函数吗?

Typescript:创建一个方法,返回的类型取决于类

是否可以将类型转换为布尔对象以返回某些内容取决于状态?

功能参数类型取决于其他参数的类型

模板函数,其中模板参数类型取决于函数参数

成员变量的类型应取决于构造函数参数的类型

Typescript回调参数取决于其他选项参数

如何让Haskell中的函数取决于其参数的类型?