将私有字段名称移动到通用助手

Posted

技术标签:

【中文标题】将私有字段名称移动到通用助手【英文标题】:Move private field name to generic helper 【发布时间】:2021-12-31 09:22:06 【问题描述】:

考虑以下代码:palyground

class A 
  private z = 0


type K = "z"
type ValidKeys = A[K] extends any ? K : never

只有当KA 的某个键子集时,类型ValidKeys 才能正常编译并与K 相同。如果我尝试向K 添加任何其他内容,则不会编译

type K = "z" | "not-a-key"

这正是我需要的行为,但我想让ValidKeys 泛型取决于AK

type ValidKeys<A, K> = ...

我怎样才能做出这样的类型?


我为什么需要它?

我正在使用 mobx 及其 documentation says:

    默认情况下,TypeScript 不允许您注释私有字段。这可以通过将相关私有字段作为通用参数显式传递来克服,如下所示:makeObservable&lt;MyStore, "privateField" | "privateField2"&gt;(this, privateField: observable, privateField2: observable )

所以我需要将包含一些私钥的类型传递给泛型函数。如果我只是传递一个文字,代码将在重命名属性后编译并在运行时中断。

所以不是

constructor() 
  makeObservable<Store, "x" | "y">(this,  x: observable, y: false )

我想写

constructor() 
  makeObservable<Store, ValidKeys<Store, "x" | "y">>(this,  x: observable, y: false )

这样如果密钥被重命名,它会在编译时中断。

我发现的唯一方法是在我的构造函数中显式编写一个 sn-p:

constructor() 
  type ExtraKeys = "x" | "y"
  type _CompilesIfOk_ExtraKeys = Store[ExtraKeys]
  makeObservable<Store, ExtraKeys>(this,  x: observable, y: false )

并且想要简化它并进入一些帮助程序。

【问题讨论】:

【参考方案1】:

我认为现在不可能,因为private members are not enumerable in keyof。这正是 MobX 要求您提供密钥的原因,因为如果可能,那么 MobX 可以自己检查它(就像它对非私有字段所做的那样)。

是的,它破坏了类型安全,但此时您无能为力(以通用方式)。

Github 上有关于该主题的讨论:https://github.com/microsoft/TypeScript/issues/22677

【讨论】:

哦..我希望有一些破解...请注意,我要求不要获取所有私钥,而只是验证指定的密钥是否存在。 这基本上是同一个问题。如果您可以验证密钥是否存在,那么您可以列出它们,反之亦然。 其实不是。我在问题中的解决方案进行了验证,但不能用于获取密钥。

以上是关于将私有字段名称移动到通用助手的主要内容,如果未能解决你的问题,请参考以下文章

Django数据模型——通用字段选项

php函数以获取数据,将具有通用字段名称的多个表连接起来并显示输出[重复]

Java字段名映射成别的名称

将具有解构赋值语法的字段提取到特定变量名

表连接存数过程及基本编程

将字段名称从 MySQL 表回显到网页 [关闭]