如何使用Observable的泛型类型创建新接口?

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

How to create new interface with Observable's generic types?

问题

我有一个带有一些Observable属性的接口,但接口的类型是未知的。是否有一种方法可以自动创建一个新的接口副本,但不包含Observable

所以这是一个示例:

interface SomeObject
{
  value1: Observable<string>;
  value2: boolean;
  value3: Observable<number>;
}

是否有一种方法可以从中创建一个新的接口,结果如下所示?

interface SomeObjectWithoutObservable
{
  value1: string;
  value2: boolean;
  value3: number;
}

也许如果有一种类似于这样的方法?

interface SomeObjectWithoutObservable extends RemoveObservable<SomeObject>
{}

只是不确定RemoveObservable会是什么样子。

英文:

Say I have an interface with some Observable properties, but the type of interface is unknown. Is there a way I can automatically create a new copy of the interface but without Observable<T>?

So here is an example:

interface SomeObject
{
  value1: Observable&lt;string&gt;;
  value2: boolean;
  value3: Observable&lt;number&gt;;
}

Is there a way I can create a new interface from that that would result in this?

interface SomeObjectWithoutObservable
{
  value1: string;
  value2: boolean;
  value3: number;
}

Maybe if there was a way to do it similar to this?

interface SomeObjectWithoutObservable extends RemoveObservable&lt;SomeObject&gt;
{}

Just not sure what RemoveObservable would look like.

答案1

得分: 2

我相信你可以通过这种方法实现它:

type RmObservable<T extends object> = {
  [key in keyof T]: T[key] extends Observable<infer R> ? R : T[key];
};

interface SomeObjectWithoutObservable extends RmObservable<SomeObject> { }

演示:https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgPICMDO0Bud0A2EAPACoB8yA3gFDLJ4ECuEAXMqTQL402iSxEKAMoB7ALYQMAKwgIw1OgzjMIARnYZsUPIRKYwUUAHNyAbiWMWAJnbpRoonBAX6ViAGZNWXPiLEQJnF0aHNuXjAATwAHFAAlcS1fPTJkCAAPSBAAE0xkUXRZeUoAXkV6AG0AawhI5FBkGsjRGA4AXXZSatq2tMyIHLyknT8SUBhoZDjKAH4p5E7uyLaLLgs+cGh4JGQxSRk5MAB1YDAAC1EmMGHdIj6s3KnEnxGUvalCw8oqZB4gA

英文:

I believe you can achieve it by this method:

type RmObservable&lt;T extends object&gt; = {
  [key in keyof T]: T[key] extends Observable&lt;infer R&gt; ? R : T[key];
};

interface SomeObjectWithoutObservable extends RmObservable&lt;SomeObject&gt; { }

Demo: https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgPICMDO0Bud0A2EAPACoB8yA3gFDLJ4ECuEAXMqTQL402iSxEKAMoB7ALYQMAKwgIw1OgzjMIARnYZsUPIRKYwUUAHNyAbiWMWAJnbpRoonBAX6ViAGZNWXPiLEQJnF0aHNuXjAATwAHFAAlcS1fPTJkCAAPSBAAE0xkUXRZeUoAXkV6AG0AawhI5FBkGsjRGA4AXXZSatq2tMyIHLyknT8SUBhoZDjKAH4p5E7uyLaLLgs+cGh4JGQxSRk5MAB1YDAAC1EmMGHdIj6s3KnEnxGUvalCw8oqZB4gA

答案2

得分: 0

感谢Tachibana!这有效。我只想添加另一个答案以扩展您的答案。我忘了提到,我总是在Observables属性名称的末尾添加$。像这样:

interface SomeObject
{
  value1: Observable<string>;
  value2: boolean;
  value3: Observable<number>;
}

所以对于这个,我也想要去掉结果中的$。所以我想出了这个:

type Replace<
  T extends string,
  S extends string,
  D extends string,
  A extends string = ''
> = T extends `${infer L}${S}${infer R}` ? Replace<R, S, D, `${A}${L}${D}`> : `${A}${T}`;

type RmObservable<T extends object> = {
  [key in keyof T as `${T[key] extends Observable<any> ? Replace<key, '$', ''> : key}`]: T[key] extends Observable<infer R> ? R : T[key];
};

interface SomeObjectWithoutObservable extends RmObservable<SomeObject> { }

感谢这个答案提供了Replace功能:https://stackoverflow.com/a/71353081/8916441

免责声明:我知道这不是完美的,因为这将替换属性名称中的任何部分的$,而不仅仅是在末尾。但我认为在我的项目中不需要担心这一点。

英文:

Thanks Tachibana! That works. I just wanted to add another answer to expand on yours. I forgot to mention that I always have a $ at the end of my property names for Observables. Like this:

interface SomeObject
{
  value1$: Observable&lt;string&gt;;
  value2: boolean;
  value3$: Observable&lt;number&gt;;
}

So for this I also wanted to remove the $ in the result. So I came up with this:

type Replace&lt;
  T extends string,
  S extends string,
  D extends string,
  A extends string = &#39;&#39;
&gt; = T extends `${infer L}${S}${infer R}` ? Replace&lt;R, S, D, `${A}${L}${D}`&gt; : `${A}${T}`;

type RmObservable&lt;T extends object&gt; = {
  [key in keyof T &amp; string as `${T[key] extends Observable&lt;any&gt; ? Replace&lt;key, &#39;$&#39;, &#39;&#39;&gt; : key}`]: T[key] extends Observable&lt;infer R&gt; ? R : T[key];
};

interface SomeObjectWithoutObservable extends RmObservable&lt;SomeObject&gt; { }

Credit to this answer for the Replace functionality: https://stackoverflow.com/a/71353081/8916441

Disclaimer: I know this is not perfect, since this would replace $ in ANY part of the property name, not just at the end. But I don't think I need to worry about that in my project.

huangapple
  • 本文由 发表于 2023年2月10日 11:38:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75406694.html
匿名

发表评论

匿名网友

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

确定