保持私有字段类型

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

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&lt;T&gt; {
    private _dummy!: T;
}

type UnwrapFoo&lt;T extends Foo&lt;any&gt;&gt; = T extends Foo&lt;infer Unwrapped&gt; ? 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&lt;T&gt; {
    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那样私有,因为有人可以对其进行子类化,但至少人们不会被引诱在实例上访问该成员。

Playground 链接到代码
"

英文:

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&lt;T&gt; {
    declare protected _dummy: T;
}

// foo.d.ts
declare class Foo&lt;T&gt; {
    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.

Playground link to code

答案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 = &#39;&#39;;
}

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 = &#39;&#39;;
}

The generated .d.ts file is as follows:

declare class Foo {
    _dummy: string;
}

huangapple
  • 本文由 发表于 2023年8月4日 20:52:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76836096.html
匿名

发表评论

匿名网友

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

确定