TypeScript 中元组的通用类型包装

2023-11-26

我需要向映射元组元素的函数添加类型声明[Foo<A>, Foo<B>, ...]到一个函数() => [A, B, ...]。我怎样才能在 TypeScript 中实现这一目标?

此示例在结构上与应用程序的相关部分类似:

interface SomethingWithAValue<T> { value: T; }

function collect(array) {
  return () => array.map(a => a.value);
}

这将返回与每个对象关联的值的元组。类型声明的作用是什么collect看起来像?

伪代码:

function collect<[SomethingWithAValue<T>...](array: [SomethingWithAValue<T>...]): () => [T...];

响应 jonrsharpe 的建议进行更新:

interface SomethingWithAValue<T> { value: T; }

function collect<T>(array: SomethingWithAValue<T>[]): () => T[] {
  return () => array.map(a => a.value);
}

type myTupleType = [string, number];

let somethings: [SomethingWithAValue<string>, SomethingWithAValue<number>];
somethings = [{ value: 'foo' }, { value: 5 }];

let fn: () => myTupleType = collect(somethings);

这不起作用:

Argument of type '[SomethingWithAValue<string>, SomethingWithAValue<number>]' is not assignable to parameter of type 'SomethingWithAValue<string>[]'.
  Types of property 'pop' are incompatible.
    Type '() => SomethingWithAValue<string> | SomethingWithAValue<number>' is not assignable to type '() => SomethingWithAValue<string>'.
      Type 'SomethingWithAValue<string> | SomethingWithAValue<number>' is not assignable to type 'SomethingWithAValue<string>'.
        Type 'SomethingWithAValue<number>' is not assignable to type 'SomethingWithAValue<string>'.
          Type 'number' is not assignable to type 'string'.

更新:从 TS3.1 开始,下面的答案已过时。我相信你现在可以使用映射元组类型 and 条件类型推断得到你想要的行为:

type ExtractValue<T extends ReadonlyArray<SomethingWithAValue<any>>> =
  { [K in keyof T]: T[K] extends SomethingWithAValue<infer V> ? V : never };

function collect<T extends ReadonlyArray<SomethingWithAValue<any>>>(
  array: T
): () => ExtractValue<T> {
  return () => array.map(a => a.value) as any;
}

让我们使用它...首先让我们通过辅助函数轻松获取元组类型tuple()它接受可变数量的参数并输出一个元组(从 TS3.0 开始这已成为可能)

type Narrowable = string | number | boolean | undefined | null | void | {};
const tuple = <T extends Narrowable[]>(...t: T) => t;

让我们看看它是否有效:

const result = collect(tuple({ value: 10 }, { value: "hey" }, { value: true }));
// const result: () => [number, string, boolean]

看起来不错!


旧答案:

没有可变参数类型在 TypeScript 中,因此无法输入通用元组(与语法不同[T...]存在)。

作为解决方法,您可以为任意长度的元组提供函数重载,直到某个合理的最大值:

function collect<A, B, C, D, E>(array: [SomethingWithAValue<A>, SomethingWithAValue<B>, SomethingWithAValue<C>, SomethingWithAValue<D>, SomethingWithAValue<E>]): () => [A, B, C, D, E];
function collect<A, B, C, D>(array: [SomethingWithAValue<A>, SomethingWithAValue<B>, SomethingWithAValue<C>, SomethingWithAValue<D>]): () => [A, B, C, D];
function collect<A, B, C>(array: [SomethingWithAValue<A>, SomethingWithAValue<B>, SomethingWithAValue<C>]): () => [A, B, C];
function collect<A, B>(array: [SomethingWithAValue<A>, SomethingWithAValue<B>]): () => [A, B];
function collect<A>(array: [SomethingWithAValue<A>]): () => [A];
function collect<T>(array: SomethingWithAValue<T>[]): () => T[] {
  // implementation
}

这应该适用于长度最大为 5 的元组,并且您可以在顶部添加其他重载以满足实践中您需要的任何内容。它既冗长又丑陋,但应该可以工作。

希望有帮助;祝你好运!

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

TypeScript 中元组的通用类型包装 的相关文章

随机推荐

  • 如果 C++ 中的构造函数抛出异常,如何清理初始化的资源

    前一天 我在采访中遇到了这个问题 所以请指导我 如果 C 中的构造函数抛出异常 如何清理初始化的资源 诀窍是使用RAII 资源获取即初始化 管理资源 如果您有指针成员 则使用智能指针而不是原始指针 一旦构造函数抛出异常 它将自动执行清理工作
  • 使用 CloseableHttpClient 不受支持的记录版本 SSLv2Hello

    我正在尝试进行 https 调用并收到以下错误 不支持的记录版本 SSLv2Hello 谁能告诉我我做错了什么吗 感谢您的帮助 这是堆栈跟踪 debug Unsupported record version SSLv2Hello javax
  • 写入小文件会阻塞 20 毫秒

    我发现在我的 Ubuntu 22 服务器上 尝试写入文件通常会导致大约 20 毫秒的延迟 即使只写入几个字节也是如此 这是一些演示该问题的基本代码 include
  • 当覆盖变量时,Python 中的内存位置会发生什么?

    In 1 class T object pass In 2 x T In 3 print x lt main T object at 0x03328E10 gt In 4 x T In 5 print x lt main T object
  • 带有 x-www-form-urlencoded 数据的 Angular 6 http post 请求

    我一直在尝试向我支持的 API 发出发布请求以发布一些数据 我已经使用邮递员尝试过这个 API 它工作正常并且数据正确返回 然而 当我尝试从我的 ionic Angular 应用程序中执行相同操作时 它根本不起作用 我已经尝试了网上大部分可
  • 按组填写缺失日期

    在我的数据中 在某些月份中存在对某些 ID 的观察 而对其他 ID 则没有观察到 例如 dat lt data frame c 1 1 1 2 3 3 3 4 4 4 c rep 30 2 rep 25 5 rep 20 3 c 2017
  • React router 将 props 传递给路由组件

    我正在尝试使用 React Router 将 props 从 app jsx 传递到我的路由组件之一 但出现以下错误 类型错误 无法读取未定义的属性 acc 这是我的 app jsx 中的代码
  • postgres psql select 语句中默认截断显示

    我有一个带有长文本列的表格 我希望能够选择所有列 但限制文本列 而无需编写每一列 select from resources 生成的输出太长 无法在 psql 中正确显示 我可以通过使用来显示一些东西substr or left 在长列上
  • 鼠标在地图上点击的位置信息 GMap.net

    我正在与 GMap net 一个使我们能够在 Win Forms 应用程序中使用 Google 地图的库 一起开发 Win Forms 应用程序 开门见山 我能够获得鼠标单击 左键单击 的坐标 纬度和经度 private void gm1
  • UICollectionViewController 以编程方式因非零布局参数错误而崩溃

    我正在创建一个UICollectionViewController以编程方式 不 我不想像每个教程一样使用 IB 和故事板 我只想使用纯代码 这是我的viewDidLoad UICollectionView UICollectionView
  • 如何使用 Homebrew 在 macOS 上安装支持 PCRE 的 Git?

    当我跑步时 git grep P
  • 迁移到 AndroidX 后 AppBarLayout 膨胀错误

    当迁移到AndroidX我遇到了这个问题 Java lang RuntimeException Unable to start activity ComponentInfo com mandarine android com mandari
  • Google Cloud Functions 包含私有库

    我正在寻找在节点中编写一个自定义库 并且希望将其包含在我的云函数中 由于这是共享代码 我希望能够在我的所有云功能中使用它 编写共享代码库并让多个云函数访问该库的最佳方式是什么 例如 假设我有两个云函数 functionS 和 functio
  • ReferenceError:PF 未定义

    我尝试过通知栏PrimeFaces 的示例 但是它不起作用 我收到以下 JS 错误 ReferenceError PF 未定义 我想我需要在使用之前包含一个库PF 函数 但我不知道哪个库以及在哪里可以找到它 JS 函数PF 仅从 4 0 开
  • Python3 - 使用 Socks5 代理的请求

    有没有办法使用socks5代理来使用TOR处理请求 我知道请求只使用http代理 import requests r requests get http www google com proxies my proxy 您可以使用socks
  • 通过反射获取Java中类的公共静态最终字段/属性的值

    假设我有一堂课 public class R public static final int 1st 0x334455 我怎样才能得到的值 1st 通过反射 首先检索类的字段属性 然后您可以检索值 如果您知道类型 则可以使用带有 null
  • 通过单击弹出窗口外部来关闭弹出窗口 javascript

    我使用本教程将弹出窗口添加到我的网页 有没有一种方法可以使当您单击弹出窗口外部 单击另一个弹出窗口时关闭弹出窗口 我尝试按照这篇文章添加一个invisibleDiv通过单击外部来关闭弹出的 div但弹出窗口仍然仅在单击按钮本身时才会移动 h
  • 有没有办法在 Visual Studio Code 中设置环境变量?

    如何在 Visual Studio Code 中设置环境变量 假设您的意思是调试会话 那么您可以包括env您的财产启动配置 如果您在工作区中打开 vscode launch json 文件或选择 调试 gt 打开配置 那么您应该会看到一组用
  • 如何在 html-webpack-plugin 中注入自定义元标记?

    我将 Webpack 与插件一起使用html webpack plugin 基于环境变量 我想注入一个标记进入决赛index html file 我该怎么做呢 您可以定义自己的模板 中简要提到了编写您自己的模板您可以将任何您想要的选项传递给
  • TypeScript 中元组的通用类型包装

    我需要向映射元组元素的函数添加类型声明 Foo a Foo b 到一个函数 gt A B 我怎样才能在 TypeScript 中实现这一目标 此示例在结构上与应用程序的相关部分类似 interface SomethingWithAValue