声明通用项数组时,如何允许推断通用参数?

2023-12-04

我遇到的情况是,我有一系列通用项目(Item),并且在项目本身内,我希望推断和具体的通用参数。

也就是说,我想要一组通用项目,但每个项目都可以有不同的通用类型,应该保留这一点。

type Item<T> = {
  value: T; 
  fn: (value: T) => void; 
}


function usesItem<T>(item: Item<T>) {

}


// This is fine - the value is inferred
usesItem({
  value: 999, 
  fn: (value) => {
      //value is inferred as number
  }
})

第一种方法,声明一个Array<Item<unknown>:

function usesItems1(items: Array<Item<unknown>>) {

}


usesItems1([{
  value: 999, 
  fn: (value) => {
    // value is unknown - we want it to be number
  }
}
])

第二种方法:从函数中引入泛型:

function usesItems2<T>(items: Array<Item<T>>) {

}

// appears to work...
usesItems2([{
  value: 999, 
  fn: (value) => {
    // value is number
  }
}
])

// ...but it doesn't really
usesItems2([{
  value: 999, 
  fn: (value) => {
    // value is number
  }
}, {
  // Type 'string' is not assignable to type 'number'.(2322)
  value: "aaa", 
  fn: (value) => {

  }
}
]); 

第三种方法——使用infer关键字,我尝试了几种方法:

type InferredItem1<T>  = T extends Item<infer R> ? Item<R> : never; 

function usesItems3(items: Array<InferredItem1<unknown>>) {

}

usesItems3([{
  //Type 'number' is not assignable to type 'never'.(2322)

  value: 999, 
  fn: (value) => {
  }
}
]); 



type InferredItem2<T extends Item<unknown>>  = T extends Item<infer R> ? Item<R> : never; 

function usesItems3b(items: Array<InferredItem2<Item<unknown>>>) {

}

usesItems3b([{
  value: 999, 
  fn: (value) => {
    // value is unknown
  }
}
]); 

TypeScript 游乐场

我怎样才能实现我想要的?

或者,如果这是不可能的,我猜想是对 Github 问题/类似问题的规范引用。


好吧,我有一些可行的东西,但它很奇怪而且很老套,我不知道我是否正确why有用。第一部分很简单:createRoutes函数需要是通用的,以便有一个类型参数可以推断:

function createRoutes<T>(routes: Route<T>[]) {
  // ...
}

奇怪的部分来了:requestBodyValidator需要写成方法而不是箭头函数,但是createHandler需要保留为箭头函数:

createRoutes([{
  route: "/a",
  method: "get",
  // method, not arrow function
  requestBodyValidator(item): Bar {
    return item as Bar;
  },
  // arrow function
  createHandler: () => {
    // value is inferred as Bar 
    return (value) => {}
  }
}])

游乐场链接

我对为什么这有效的最好猜测是通过requestBodyValidator一个方法,在推断整个对象的类型时会考虑它的类型,因为 Typescript 在这个意义上将方法视为“对象的一部分”。然后因为createHandler是一个箭头函数,Typescript 将其视为子表达式,并且其类型是从上下文推断的。由于在推断对象类型时此子表达式没有已知类型,因此无法使用其类型to推断对象的类型。无论如何,这是我最好的猜测;也许原因是别的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

声明通用项数组时,如何允许推断通用参数? 的相关文章

随机推荐

  • 根据 json 值路由到不同的操作

    我想根据特定 json 参数的值将请求路由到不同的操作 例如 给定以下 json 数据 type type1 type1data type1value and type type2 type2data type2value 我希望能够在我的
  • android AlarmManager 无法唤醒手机

    我想要在某个时间显示一个活动 为此 我使用 AlarmManager 当设备唤醒时它可以正常工作 但如果设备处于睡眠状态则不会唤醒它 我设置闹钟的代码 Calendar alarmTime Calendar getInstance alar
  • 为什么不评估 && 运算符的右侧? [复制]

    这个问题在这里已经有答案了 小疑问 为什么下面代码的输出是1 为什么不3 int i 0 boolean t true f false b b t i 0 b f i 2 gt 0 System out println i 条件与运算符 是
  • 在 MVC6 中创建自定义模型绑定器的正确方法是什么?

    我正在尝试按照中的步骤操作本文使用 vNext 项目和 mvc 6 我一直在阅读代码here但仍然有点不确定如何实现这一点 有没有人有一个可以分享的可行示例或为我指明正确的方向 我特别想知道如何注册自定义绑定器 以及我将从哪些类继承 因为
  • 具有不同数据类型答案的调查的 SQL 设计

    我正在开展一项在线调查 大多数问题的答案等级为 1 5 如果我们需要向调查添加问题 我会使用一个简单的 Web 表单 该表单会插入到相应的表中 瞧 调查提出了新问题 没有新代码或对数据库结构进行更改 我们被要求添加可以有不同数据类型答案的调
  • 如何保存Jenkins配置?

    有没有办法在 Git 或其他任何地方保存管道配置或项目配置 以便当我的 Jenkins 机器崩溃时 我可以将保存的配置迁移到新的 Jenkins 实例中 我会 作为开始 让自己 https wiki jenkins io display J
  • 有没有一个库可以模拟 facebook 的“Link Detect”? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我正在寻找编写一个库 可以
  • 寻找有 2 个点的向量

    我正在帮助我的朋友玩 pygame 但我们被困住了 所以我们正在尝试获取射弹的方向 但我们不知道如何获取 例如 1 1 将走向东南 1 1 将走向 NE 1 1 将走向西北 和 1 1 将去 SW 我们需要某种方程来获取玩家位置和鼠标位置并
  • 从 Google Assistant 启动我的应用程序(如果有)

    要求是如果用户命令 GA 启动我的 Android 应用程序查找附近的麦当劳餐厅其中 McDonald 是应用程序名称 由于用户没有提及他 她想要在 McDonald 应用程序中进行搜索 因此应用程序无法使用定义的意图过滤器来处理明确的意图
  • NSTimer 不会失效

    我在使计时器失效时遇到问题 property nonatomic strong NSTimer timer 在成功的块内 我在主线程上分配和设置计时器 dispatch async dispatch get main queue self
  • Mongoose(或 MongoDB)中的 TransientTransactionError 是什么?

    I have server js and db js The db js文件使用 Mongoose 与我的数据库交互 我使用server js从中调用函数db js var mongoose require mongoose mongoos
  • Cassandra Datastax 驱动程序在访问器上设置分页状态

    我正在使用 Datastax 可爱的 cassandra java 驱动程序 我试图将所有查询字符串封装到内置访问器中以进行映射 但我需要能够设置查询的分页状态 我发现这可以通过普通的语句 SimpleStatement 实现 但我还没有找
  • 如何以Google方式隐藏库源代码?

    例如 我有一个library我想保护源代码不被查看 我想到的第一个方法是为私有函数创建公共包装器 如下所示 function executeMyCoolFunction param1 param2 param3 return execute
  • 如何在xslt中提取这种格式

    我有一个 xml 结构
  • Bash 故障排除:不是有效的标识符

    初学者试图让管道在 bash 中工作 如果有人能明白为什么当我运行以下命令时我会得到 bash i not a valid identifier 这真的很有帮助 另外如果还有其他错误请告诉我 for i in home regionstex
  • Postgres 9.4 Django 1.9 获取所有 json 键

    我在 django 模型中有一个 JSONField 如下所示 from django db import models from django contrib postgres fields import JSONField class
  • JBoss / HotSpot JVM 崩溃

    我们有一个基于 Jboss 构建的 Web 应用程序 已经投入生产多年 在过去的 18 个月里 它从未下降过 然而 最近两天 jvm崩溃了4次 当 JVM 崩溃时 我们会收到一份我正在努力解读的错误报告 我看过其他几个崩溃报告 在这个网站和
  • Keras 中的自定义损失函数

    我正在研究一种图像类增量分类器方法 使用 CNN 作为特征提取器和全连接块进行分类 首先 我对 VGG 训练网络进行了微调以完成新任务 一旦网络针对新任务进行了训练 我就会为每个类别存储一些示例 以避免忘记新类别何时可用 当某些类可用时 我
  • 从类路径资源文件夹获取文件列表? [复制]

    这个问题在这里已经有答案了 我正在尝试从资源文件夹设置 JFX ImageView 图像 但似乎无法获得不会引发异常的适当 URL 字符串文件路径 var x getRandomImageFromPackage pictures toStr
  • 声明通用项数组时,如何允许推断通用参数?

    我遇到的情况是 我有一系列通用项目 Item 并且在项目本身内 我希望推断和具体的通用参数 也就是说 我想要一组通用项目 但每个项目都可以有不同的通用类型 应该保留这一点 type Item