Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One type definition to cover properties of primitive and generic types without unioning

This is the pattern that requires me to define two types that I would like to refactor/consolidate:

...
.then((result1: any) => {
    let promises = {
       one: $q.when(val1),
       two: $q.when(val2)
    };
    return $q.all(promises);
})
.then((resolvedPromises: any) => {
    // use
    resolvedPromises.one...
    resolvedPromises.two
});

I would like to define type of promises and resolvedPromises but as they are type related I would like to define a single type (likely generic) instead of defining two types with similar definition.

So instead of:

public interface ResultingType {
    [id: string]: any,
    one: Something1,
    two: Something1
}

public interface PromisingType {
    [id: string]: ng.IPromise<any>,
    one: ng.IPromise<Something1>,
    two: ng.IPromise<Something2>
}

The problem is that from the usual generic type perspective we provide the inner-most type to be injected into, but in my case I need to somehow define the outer type either being ng.IPromise<> or nothing actually.

I also don't want to end up with a single type that would allow both types:

public interface ConsolidatedType {
    [id: string]: any | ng.IPromise<any>,
    one: Something1 | ng.IPromise<Something1>,
    two: Something2 | ng.IPromise<Something2>
}

This would allow for mixing and matching in invalid places. So that's a no-go. Is there any other way to actually have a single type without code repetition that only wraps types into promises?

like image 366
Robert Koritnik Avatar asked Dec 02 '25 10:12

Robert Koritnik


1 Answers

How about:

interface BaseType<T, S> {
    [id: string]: T;
    one: S;
    two: S;
}

And then:

...
.then((result1: any) => {
    let promises = {
       one: $q.when(val1),
       two: $q.when(val2)
    } as BaseType<ng.IPromise<any>, ng.IPromise<Something1>>;
    return $q.all(promises);
})
.then((resolvedPromises: BaseType<any, Something1>) => {
    // use
    resolvedPromises.one...
    resolvedPromises.two
});

You can also create "shortcuts":

interface PromiseType extends BaseType<ng.IPromise<any>, ng.IPromise<Something1>> {}

interface ValueType extends BaseType<any, Something1> {}

And then:

...
.then((result1: any) => {
    let promises = {
       one: $q.when(val1),
       two: $q.when(val2)
    } as PromiseType;
    return $q.all(promises);
})
.then((resolvedPromises: ValueType) => {
    // use
    resolvedPromises.one...
    resolvedPromises.two
});
like image 177
Nitzan Tomer Avatar answered Dec 04 '25 23:12

Nitzan Tomer