将私有字段名称移动到通用助手
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
只有当K
是A
的某个键子集时,类型ValidKeys
才能正常编译并与K
相同。如果我尝试向K
添加任何其他内容,则不会编译
type K = "z" | "not-a-key"
这正是我需要的行为,但我想让ValidKeys
泛型取决于A
和K
:
type ValidKeys<A, K> = ...
我怎样才能做出这样的类型?
我为什么需要它?
我正在使用 mobx 及其 documentation says:
默认情况下,TypeScript 不允许您注释私有字段。这可以通过将相关私有字段作为通用参数显式传递来克服,如下所示:
makeObservable<MyStore, "privateField" | "privateField2">(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
【讨论】:
哦..我希望有一些破解...请注意,我要求不要获取所有私钥,而只是验证指定的密钥是否存在。 这基本上是同一个问题。如果您可以验证密钥是否存在,那么您可以列出它们,反之亦然。 其实不是。我在问题中的解决方案进行了验证,但不能用于获取密钥。以上是关于将私有字段名称移动到通用助手的主要内容,如果未能解决你的问题,请参考以下文章