从对象数组构造 TypeScript 类型

2023-11-30

我有数据库表的以下架构列(用于西瓜数据库)。

const columns = [
  { name: "created_at", type: "number", isOptional: true },
  { name: "created_by", type: "string" },
  { name: "is_corrupt", type: "boolean", isOptional: true },
];

我想创建一个泛型,它将根据上面的示例创建以下类型,我该怎么做?

type ExpectedInferredTypeFromColumns = {
  created_at: number | null;
  created_by: string;
  is_corrupt: boolean | null;
};

我的尝试:

type InferTypeFromColumns<T extends ReadonlyArray<Column>> = {
  [K in T extends ReadonlyArray<infer U>
    ? U extends { name: string }
      ? U["name"]
      : never
    : never]: T extends ReadonlyArray<infer U>
    ? U extends { type: "number"; isOptional: true }
      ? number | null
      : U extends { type: "number" }
      ? number
      : U extends { type: "string"; isOptional: true }
      ? string | null
      : U extends { type: "string" }
      ? string
      : U extends { type: "boolean"; isOptional: true }
      ? boolean | null
      : U extends { type: "boolean" }
      ? boolean
      : never
    : never;
};

type MyInferredType = InferTypeFromColumns<typeof columns>;
// Produces: => 
// type MyInferredType = {
//     created_at: string | number | boolean | null;
//     created_by: string | number | boolean | null;
//     is_corrupt: string | number | boolean | null;
// }

正如你所看到的,我的尝试不太符合我的要求ExpectedInferredTypeFromColumns


就这样:操场

const columns = [
  { name: "created_at", type: "number", isOptional: true },
  { name: "created_by", type: "string" },
  { name: "is_corrupt", type: "boolean", isOptional: true },
] as const; // define as const so `columns[number]` gives precise type inference

type Column = {
  name: string;
  type: "number" | "string" | "boolean"
  isOptional?: boolean
}

type TypeMapper = {
  boolean: boolean;
  string: string;
  number: number;
}

// You need to create a union depending if `isOptional` is defined or not
type InferTypeFromColumns<T extends ReadonlyArray<Column>> = {
  [K in T[number] as K['name']]: TypeMapper[K['type']] | (K['isOptional'] extends true ? null : never)
}

type Test = InferTypeFromColumns<typeof columns>
/*
type Test = {
    created_at: number | null;
    created_by: string;
    is_corrupt: boolean | null;
}
*/

如果您需要可选键,则需要将可选键和必需键进行交集像这样:

type RequiredInferTypeFromColumns<T extends ReadonlyArray<Column>> = {
  [K in T[number] as K['isOptional'] extends true ? never : K['name']]: TypeMapper[K['type']]
}

type OptionalInferTypeFromColumns<T extends ReadonlyArray<Column>> = {
  [K in T[number] as K['isOptional'] extends true ? K['name'] : never]?: TypeMapper[K['type']] | null
}

type Intersection<A, B> = A & B extends infer U
  ? { [P in keyof U]: U[P] }
  : never;

type Test = Intersection<RequiredInferTypeFromColumns<typeof columns>, OptionalInferTypeFromColumns<typeof columns>>
/*
type Test = {
    created_by: string;
    created_at?: number | null | undefined;
    is_corrupt?: boolean | null | undefined;
}
*/

这个答案的灵感来自于这个解决方案:有条件申请?每个属性的映射类型中的修饰符

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

从对象数组构造 TypeScript 类型 的相关文章

随机推荐

  • MVC6 TagHelpers 一次性

    在较旧的 MVC HTML 帮助程序中 可以使用IDisposable包装内容 例如BeginForm助手会自动换行 stuff 有结束语form tag stuff MVC6 TagHelpers 支持这种内容包装吗 例如我想要这个
  • 如何将 Bundle 从 Fragment 传递到 Fragment

    我在我的应用程序中使用片段 这是我的第一个片段 它只是简单地膨胀了 xml 文件 public class FragmentA extends SherlockFragment Context myContext appContext Ov
  • 如何在谷歌应用程序引擎模板上获取cookie值

    我正在开发一个应用程序来了解 python 和 Google App Engine 我想从 cookie 中获取值并在模板上打印以隐藏或显示某些内容 是否可以 哪种会话系统最适合与谷歌应用程序引擎一起使用 在 gae 和模板上使用会话的最佳
  • Angular4中的浏览器关闭事件

    我如何检测角度 4 0 2 中的浏览器关闭事件 我努力了 HostListener window unload event unloadHandler event HostListener window beforeunload event
  • std::thread 构造函数如何检测右值引用?

    显然可以将右值引用传递给std thread构造函数 我的问题是这个构造函数的定义参考参数 它说这个构造函数 template lt class Function class Args gt explicit thread Function
  • 如何在python中将对象数组转换为普通数组

    我有一个看起来像这样的对象数组 array array 2 4567 dtype object array 3 4567 dtype object array 4 4567 dtype object array 5 4567 dtype o
  • Java 应用程序挂在 in.hasNext(); 上

    我正在开发通过套接字进行通信的战舰摇摆应用程序 private ServerSocket server private Socket connection private PrintWriter out private Scanner in
  • 如何在资源管理器的重命名事件中挂钩 C++

    我不能比我的标题更清楚了 P 我想每当用户在 Windows 资源管理器中重命名文件时 并且仅在资源管理器中 运行我的程序 这是一个简单的模型 一个简单的教程链接将会非常有帮助 我什么也没找到 先感谢您 附 我是 C 新手 看来 Windo
  • Room 无法验证数据完整性

    我在使用房间数据库运行程序时收到此错误 Room cannot verify the data integrity Looks like you ve changed schema but forgot to update the vers
  • 使用 iOS 获取 Facebook 新闻源?

    我从适用于 iOS 的 Facebook SDK 开始 在我的应用程序中 我尝试获取用户新闻源并将其加载到 uitableview 中 事实证明这很棘手 我也找不到任何有关它的文档 使用 Facebook SDK 您可以使用以下方式调用 F
  • 使用 App 目录和 next-intl 翻译 Next.js 13 中的 URL

    我目前正在开发多语言 Next js 13 应用程序 并使用 next intl 包进行国际化 我一直在尝试为我的路线设置翻译后的网址 但遇到了一些问题 这是我想要实现的目标的一个例子 如果源语言是丹麦语 则路径可以是 mypage om
  • 使用自定义域部署到 Heroku [关闭]

    Closed 这个问题是无关 目前不接受答案 我已经从 My app heroku com 运行该应用程序并且它可以工作 并且我已经在我的域之间设置了 DNS 但是每当我从我指定的域打开我的应用程序时 heroku 会说 请参阅文档 如果您
  • 为基于 create-react-app 的项目运行 npm build 后在运行时读取环境变量

    我是 React 新手 我将部署一个 React 项目 React项目由create react app创建 然后生产代码由 npm build 构建 并由Express托管 在项目中 有一些对 API 服务器的 fetch 调用 其中的
  • Spark 闭包参数绑定

    我正在 Scala 中使用 Apache Spark 我在尝试使用第二个 RDD 中的数据操作一个 RDD 时遇到问题 我试图将第二个 RDD 作为参数传递给针对第一个 RDD 进行 映射 的函数 但似乎在该函数上创建的闭包绑定了该值的未初
  • jQuery - 如何将字符串中的每个字符包装在跨度中

    如何将div的字符转换为span 例如 我想转换这个 div Hello World div 进入这个 div span H span span e span span l span span l span span o span span
  • 如何将简单类序列化/反序列化为 XML 并返回

    有时我想模拟类的存储数据 而不需要设置与数据库的往返 例如 假设我有以下课程 public class ShoppingCart public List
  • 工作自动构建增量 Visual Studio 插件

    我正在寻找一个working Visual Studio 2012插件会自动增加我的内部版本号 就像是http autobuildversion codeplex com 但这对我不起作用 如果重要的话 我正在使用 Visual Studi
  • 使用 gson 解析 JSON 数组

    我在解析从 javascript 获取的 JSON 时遇到问题 JSON的格式是这样的 positions x 50 y 50 x 82 y 50 x 114 y 50 x 146 y 50 positions x 210 y 50 x 2
  • WPF NotifyPropertyChangeds 是否编组到调度程序?

    如果我更新一个在绑定控件调度程序之外的线程上抛出 INotifyPropertyChanged 的 属性 更新会被强制编组到该调度程序吗 BackgrounWorker Run gt blah Blahness 2 notifies pro
  • 从对象数组构造 TypeScript 类型

    我有数据库表的以下架构列 用于西瓜数据库 const columns name created at type number isOptional true name created by type string name is corru