英文:
Keep private field type
问题
以下是翻译好的内容:
我有一个相对奇怪的情况,我只需要一个类属性来保存一个泛型类型,而不是因为我想在运行时访问它。
我有一个类和实用类型如下:
class Foo<T> {
private _dummy!: T;
}
type UnwrapFoo<T extends Foo<any>> = T extends Foo<infer Unwrapped> ? Unwrapped : never;
属性_dummy
从未以任何方式访问过,但它是必需的,以使UnwrapFoo
正常工作。否则,如果没有它,T
将被丢弃,意味着 UnwrapFoo
无法再推断它了。
我的问题是,当 TypeScript 生成相应的 .d.ts
文件时,它会擦除 _dummy
的类型,因为它是一个私有属性。生成的类型定义如下:
class Foo<T> {
private _dummy;
}
现在,T
再次被丢弃,UnwrapFoo
停止工作。有没有办法保留 _dummy
的类型?我可以将其设为公共属性,但我不喜欢这样做,因为它纯粹是一个内部属性,不应该被 Foo
类的用户访问(而且无论如何,它始终是 undefined
,尽管其类型是什么)。
英文:
I have a somewhat strange case where I need a class property merely to hold on to a generic type and not because I want to access it at runtime.
I have a class and utility type like this:
class Foo<T> {
private _dummy!: T;
}
type UnwrapFoo<T extends Foo<any>> = T extends Foo<infer Unwrapped> ? Unwrapped : never;
The property _dummy
is never accessed in any way, but it is required for UnwrapFoo
to work. Otherwise, were it not present, T
would be discarded meaning that UnwrapFoo
can not infer it anymore.
My issue is that, when TypeScript generates the respective .d.ts
file, it erases the type of _dummy
, as it is a private property. The generated typings look like this:
class Foo<T> {
private _dummy;
}
Now, T
is being discarded again and UnwrapFoo
ceases to work. Is there a good way to keep the type of _dummy
? I could make it public, but I do not like that because it is purely an internal property that should never be accessed by a user of the Foo
class (also, it is always undefined
anyway, despite what its type says).
答案1
得分: 1
以下是您要翻译的内容:
"不过,private
类属性的类型似乎没有很好地记录,而且通过 --declaration
编译器选项生成的 .d.ts
文件故意对其进行了抑制,没有改变的方法。在官方文档方面,我只看到了在相关的 GitHub 问题中的这个评论,以及声明发射器源代码积极地抑制了除构造函数参数属性之外的private
成员的类型注释。
假设您需要保留一个用于此目的的虚拟字段,并且通常不希望从外部访问它,您可以考虑将其更改为protected
属性:
// foo.ts
class Foo<T> {
declare protected _dummy: T;
}
// foo.d.ts
declare class Foo<T> {
protected _dummy: T;
}
这并不像private
那样私有,因为有人可以对其进行子类化,但至少人们不会被引诱在实例上访问该成员。
英文:
It doesn't seem to be well-documented, but the types of private
class properties are intentionally suppressed from .d.ts
files generated via the --declaration
compiler option, and there's no way to change that. In terms of official documentation, I only see this comment in a related GitHub issue, and the fact that the declaration emitter source code actively suppresses type annotation for private
things except in constructor parameter properties.
Assuming you need to keep a dummy field for this purpose and you don't want it accessible from the outside in general, you might consider changing it to a protected
property instead:
// foo.ts
class Foo<T> {
declare protected _dummy: T;
}
// foo.d.ts
declare class Foo<T> {
protected _dummy: T;
}
This isn't as private as private
, since someone could come along and subclass it, but at least people won't be tempted to access that member on an instance.
答案2
得分: 0
总的来说,请记住,在TypeScript中的类型并不会生成JavaScript代码,它们仅仅是为了你和编译器在编写代码时了解元数据。因此,类型不能保存到变量中。
关于生成.d.ts
文件的问题,要记住类型不会出现,因为属性是private
的。类外部无法访问它,因此在类型定义文件中为它添加类型是没有意义的。考虑以下示例:
class Foo {
private _dummy: string = '';
}
生成的.d.ts
文件如下:
declare class Foo {
private _dummy;
}
然而,如果是public
属性,它会有类型信息,因为使用.d.ts
文件的其他部分可以访问public
属性。
class Foo {
public _dummy: string = '';
}
生成的.d.ts
文件如下:
declare class Foo {
_dummy: string;
}
英文:
So in general keep in mind that types in TypeScript do not generate and JavaScript code, they are metadata only for you and the compiler to know about as you write code. Because of this, types cannot be saved to variables.
Regarding the generation of the .d.ts
files, keep in mind that the type is not present because the property is private
. Nothing outside the class can access it, so putting a type on it for a type definition file is useless. Consider the following:
class Foo {
private _dummy: string = '';
}
The generated .d.ts
file is as follows:
declare class Foo {
private _dummy;
}
However, a public
property will have type information since other things that use the .d.ts
file will have access to a public
property.
class Foo {
public _dummy: string = '';
}
The generated .d.ts
file is as follows:
declare class Foo {
_dummy: string;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论