[英]Is it possible to get the type from a generic, given as parameter
I created a function that takes an object of subscribers, as seen below. 我创建了一个带有订阅者对象的函数,如下所示。
public subscribers = {
count: <EventEmitter<number>>new EventEmitter<number>(),
staticCount: <EventEmitter<number>>new EventEmitter<number>()
};
This function waits for both observables to complete, and returns an object with the keys of the object it received, as value the emitted value from the EventEmitter. 此函数等待两个可观察对象都完成,并返回一个带有接收到的对象的键的对象,作为从EventEmitter发出的值的值。
type AnyType<T> = {
[P in keyof T]: any;
}
function ZipObservable<T extends { [name: string]: EventEmitter<any>}>
(observables: T): Observable<AnyType<T>> {
const m = CreateMapFromObject(observables);
const o = new Subject<any>();
Observable.zip(...Array.from(m.values())).subscribe((res) => {
const keys = m.keys();
const c = res.reduce((r, v) => {
const k = <string>keys.next().value;
r[k] = v;
return r
}, {});
/**
*
*/
o.next(c);
o.complete();
});
return o.asObservable();
}
My current problem is at the type of the value set in the returned object. 我当前的问题是在返回对象中设置的值的类型。 The object its keys are typed (as you can see in the image).
键入键的对象(如您在图像中看到的)。
I also want the type of the value to be set to number (in this case). 我还希望将值的类型设置为数字(在这种情况下)。 I created a type;
我创建了一个类型;
AnyType<T>
that's able to set the returned object its keys. 能够将返回的对象设置为其键的
AnyType<T>
。 Is it possible to also get it to set its value's type? 是否还可以获取它来设置其值的类型?
The type i want it to become, comes from the parameter, which receives a generic; 我希望它成为的类型来自于接收通用值的参数;
EventEmitter<number>
. EventEmitter<number>
。
Working type safety for the returned object. 返回对象的工作类型安全性。
So, you want ZipObservable
to return an object of type Observable<T>
, where the input parameter has the same keys as T
but the values for each key K
are EventEmitter<T[K]>
(where T[K]
is the type of the property value of the K
key of type T
). 因此,您希望
ZipObservable
返回类型为Observable<T>
的对象,其中输入参数与T
具有相同的键,但每个键K
的EventEmitter<T[K]>
(其中T[K]
是类型类型T
的K
键的属性值的值)。 That is definitely achievable, through mapped types and inference from mapped types : 通过映射类型和从映射类型的推断,绝对可以实现:
First let's define a mapped type which takes every property in T
and converts it to an EventEmitter<>
of the appropriate type: 首先让我们定义一个映射类型,该类型接受
T
每个属性并将其转换为适当类型的EventEmitter<>
:
type EventEmitters<T> = {
[K in keyof T]: EventEmitter<T[K]>
}
Now the ZipObservable
function signature can be written directly (I will leave the implementation up to you): 现在可以直接编写
ZipObservable
函数签名(我将把实现留给您):
declare function ZipObservable<T>(eventEmitters: EventEmitters<T>): Observable<T>;
And it works because of inference from mapped types: 它之所以能够工作,是因为从映射类型推断出来:
const ret = ZipObservable(subscribers).subscribe(r => r.count * 3); // no error
Hope that helps; 希望能有所帮助; good luck!!
祝好运!!
Thanks a lot to @jcalz 非常感谢@jcalz
You got me on the right path. 你让我走上了正确的道路。 Your code worked.
您的代码有效。 It removed my type safety though, so i tweaked it a little bit.
它虽然消除了我的类型安全性,所以我对其进行了一些调整。
-- EDIT - 编辑
It didn't remove my type safety. 它并没有消除我的类型安全性。 My editor just doesn't recognize the keys on the returned object.
我的编辑器无法识别返回对象上的键。 It does when i use the code below.
当我使用以下代码时,它确实可以。
type EmittedReturnType<T> = {
[K in keyof T]: T[K]
}
type EventEmitters<T> = {
[K in keyof T]: EventEmitter<T[K]>
}
So, 所以,
I created two types; 我创建了两种类型; First type to be the parameter type.
第一种类型为参数类型。 The second type to be the return type.
第二种类型是返回类型。
declare function ZipObservable<T>(observables: EventEmitters<T>): Observable<EmittedReturnType<T>>
Which results in; 结果是;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.