简体   繁体   English

是否有可能从泛型中获取类型,以参数形式给出

[英]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具有相同的键,但每个键KEventEmitter<T[K]> (其中T[K]是类型类型TK键的属性值的值)。 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; 结果是;

A type safe object. 类型安全的对象。

A type safe assign 类型安全分配

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM