【问题标题】:How write generic interface which maps to properties only with selected types of T?如何编写仅使用选定类型的 T 映射到属性的通用接口?
【发布时间】:2018-02-19 08:36:58
【问题描述】:

假设我有一个用户对象:

export class User {

  @Column()
  public email: string;

  @Column({ nullable: true })
  public name: string;

  @Column({ nullable: true })
  public birthDate: Date;

  @OneToMany(type => Article, article => article.author)
  public articles: Promise<Article[]>;

} 

我可以使用以下界面创建带有类型信息的部分选择:

export interface Seed<T> {
  rows: {[K in keyof T]?: T[K]}[];
}

问题如下:通过这种方法,我看到了实体的所有关系,所以我必须使类的键选择部分接受种子,例如:

const USER_SEED: Seed<User> = {
  email: test@mail.com,
  name: 'Johny Test',
  birthDate: new Date('1990-01-08'),
} 

这可能会导致不正确的种子,其中未提供不可为空的字段或提供了表中不存在的字段,因为它是一个关系。

我的问题是如何创建具有所选类型的键选择?在这种情况下,我会选择字符串、数字和日期类型的键

【问题讨论】:

  • 如果属性可以为空,为什么不在类定义中将其标记为空?
  • createdAt或主键之类的字段,一直存在,但在为数据库做种时不需要,因为它是计算出来的。
  • 您可能将rows 键入为Array&lt;Partial&lt;User&gt; &amp; Pick&lt;User, "name" | "email"&gt;&gt;,其中“name”和“email”是唯一的非空属性。但是您必须手动更新非空列。
  • 我尽量避免手动操作。
  • 不应该用rows 属性初始化USER_SEED 吗?

标签: typescript generics


【解决方案1】:

您正在寻找Pick,它也接受密钥类型:

Pick<{a: number, b: boolean, c: string}, 'a' | 'b'> ==> {a: number, b: boolean}

您不能按类型选择键。

【讨论】:

  • 谢谢,我知道Pick,将新属性添加到模型时的问题,在编译时没有任何警告我必须更新我的种子,这就是我寻找的原因用于自动选择类型。
  • 在运行时添加的东西不能在编译时描述。如果您愿意,可以查看运行时类型系统,例如 MobX 状态树。
  • 它不是在运行时添加的,我的意思是如果我修改模型,添加一个新列,在重新编译时它将是可见的。然而,当我研究时,似乎我想要的只能通过反射来实现。
【解决方案2】:

将你的类一分为二,并将种子应用到基础类。

export abstract class UserFields {

  @Column()
  public email: string;

  @Column({ nullable: true })
  public name: string;

  @Column({ nullable: true })
  public birthDate: Date;

}

export class User extends UserFields {

  @OneToMany(type => Article, article => article.author)
  public articles: Promise<Article[]>;

} 

export interface Seed<T> {
  rows: {[K in keyof T]: T[K]}[];
}

const USER_SEED: Seed<UserFields> = {
    rows: [
        {
            email: "test@mail.com",
            name: 'Johny Test',
            birthDate: new Date('1990-01-08')
        }
    ]
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 2022-07-06
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多