用于查询嵌套对象的带点符号的TypeScrip类型安全字符串 [英] Typescript type safe string with dot notation for query nested object

查看:25
本文介绍了用于查询嵌套对象的带点符号的TypeScrip类型安全字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用TypeScrip和Firebase,我有一个带有此函数的小抽象层,用于根据文档的字段名称和值搜索唯一的文档。

  where<K extends keyof (T & DocumentEntity)>(fieldName: K, operator: WhereFilterOp, value: unknown): Query<T> {
    this.addCriterion(new WhereCriterion(fieldName as string, operator, value));
    return this;
  }

当我想使用文档底部的字段进行查询时,这种方法效果很好,例如:

型号:

order: Order = {
  orderId: baseId
  item: { ... }
  price: { ... }
  restaurant: {
    restaurantId: nestedId
    name: chezGaston
  }
}

查询:

    const order = await this.documentPersistence.findUnique(
      new Query<order>().where('orderId', '==', incomingOrderId)
    );

但现在我要根据嵌套对象的ID进行查询。

const order = await this.documentPersistence.findUnique(
      new Query<order>()
        .where('restaurant.restaurantId', '==', integration),
    );

这会给我一个静态错误TS2345: Argument of type '"restaurant.restaurantId"' is not assignable to parameter of type 'keyof Order'.

如何修复我的函数,使其接受嵌套对象作为我的对象的键?

我不想使用// @ts-ignore

推荐答案

您可以从TypeScrip4.1开始执行此操作。

单击操场示例查看实际操作:

TypeScript Playground

Original Twitter Post

相关代码如下:

type PathImpl<T, K extends keyof T> =
  K extends string
  ? T[K] extends Record<string, any>
    ? T[K] extends ArrayLike<any>
      ? K | `${K}.${PathImpl<T[K], Exclude<keyof T[K], keyof any[]>>}`
      : K | `${K}.${PathImpl<T[K], keyof T[K]>}`
    : K
  : never;

type Path<T> = PathImpl<T, keyof T> | keyof T;

type PathValue<T, P extends Path<T>> =
  P extends `${infer K}.${infer Rest}`
  ? K extends keyof T
    ? Rest extends Path<T[K]>
      ? PathValue<T[K], Rest>
      : never
    : never
  : P extends keyof T
    ? T[P]
    : never;

declare function get<T, P extends Path<T>>(obj: T, path: P): PathValue<T, P>;

const object = {
  firstName: "Diego",
  lastName: "Haz",
  age: 30,
  projects: [
    { name: "Reakit", contributors: 68 },
    { name: "Constate", contributors: 12 },
  ]
} as const;

get(object, "firstName"); // works
get(object, "projects.0"); // works
get(object, "projects.0.name"); // works

get(object, "role"); // type error

这篇关于用于查询嵌套对象的带点符号的TypeScrip类型安全字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆