英文:
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<string>;
value2: boolean;
value3: Observable<number>;
}
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<SomeObject>
{}
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<T extends object> = {
[key in keyof T]: T[key] extends Observable<infer R> ? R : T[key];
};
interface SomeObjectWithoutObservable extends RmObservable<SomeObject> { }
答案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<string>;
value2: boolean;
value3$: Observable<number>;
}
So for this I also wanted to remove the $
in the result. So I came up with this:
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 & string as `${T[key] extends Observable<any> ? Replace<key, '$', ''> : key}`]: T[key] extends Observable<infer R> ? R : T[key];
};
interface SomeObjectWithoutObservable extends RmObservable<SomeObject> { }
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论