扩展类型以允许额外的字段

huangapple go评论97阅读模式
英文:

Extending a type to allow additional fields

问题

我有一个通用的方法,用于为数据库创建节点,我希望这个方法能够允许使用类型中已知的字段以及任何额外的字段。

以下是相关的方法代码:

create<A extends string, P extends Partial<Record<keyof T['fields'], any>>>(
    alias: A,
    node: T,
    parameters: P,
): this {
    const properties = Object.entries(parameters)
        .map(([key, value]) => `${key}: "${value}"`)
        .join(', ');

    this.query.push(`CREATE (${alias}:${node.label} {${properties}})`);
    return this;
}

当我使用这个方法时:

const query = this.cypherBuilder
  .create('m', Author, {
    name,
    image,
    description,
    lifeYears,
    didntExisit: 22,  // 这个字段不是Author的字段之一。
  })
  .return('m')
  .build();

TypeScript没有对didntExisit字段进行任何投诉,尽管它不是Author的字段之一。

英文:

I have a generic method designed to create nodes for a database, and I want this method to allow both known fields from a type and any additional fields.

Here's the method in question:

create&lt;A extends string, P extends Partial&lt;Record&lt;keyof T[&#39;fields&#39;], any&gt;&gt;&gt;(
    alias: A,
    node: T,
    parameters: P,
): this {
    const properties = Object.entries(parameters)
        .map(([key, value]) =&gt; `${key}: &quot;${value}&quot;`)
        .join(&#39;, &#39;);

    this.query.push(`CREATE (${alias}:${node.label} {${properties}})`);
    return this;
}

When I use this method:

const query = this.cypherBuilder
  .create(&#39;m&#39;, Author, {
    name,
    image,
    description,
    lifeYears,
    didntExisit: 22,  // This field isn&#39;t part of Author&#39;s fields.
  })
  .return(&#39;m&#39;)
  .build();

TypeScript didn't complains about the didntExisit field, which isn't part of Author's fields.

答案1

得分: 1

一个解决方法是使用映射类型来根据类型的已知字段限制参数对象的键。以下是如何实现这一点的示例代码:

type RestrictedParameters<T> = Partial<{ [K in keyof T['fields']]: any }>;

class CypherBuilder<T> {
    // ... 其他方法 ...

    create<A extends string>(
        alias: A,
        node: T,
        parameters: RestrictedParameters<T>,
    ): this {
        const properties = Object.entries(parameters)
            .map(([key, value]) => `${key}: "${value}"`)
            .join(', ');

        this.query.push(`CREATE (${alias}:${node.label} {${properties}})`);
        return this;
    }
}
英文:

A workaround is to use a mapped type to restrict the keys of the parameters object based on the type's known fields. Here's how you can achieve this:

type RestrictedParameters&lt;T&gt; = Partial&lt;{ [K in keyof T[&#39;fields&#39;]]: any }&gt;;

class CypherBuilder&lt;T&gt; {
    // ... other methods ...

    create&lt;A extends string&gt;(
        alias: A,
        node: T,
        parameters: RestrictedParameters&lt;T&gt;,
    ): this {
        const properties = Object.entries(parameters)
            .map(([key, value]) =&gt; `${key}: &quot;${value}&quot;`)
            .join(&#39;, &#39;);

        this.query.push(`CREATE (${alias}:${node.label} {${properties}})`);
        return this;
    }
}

huangapple
  • 本文由 发表于 2023年8月9日 03:05:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76862533.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定