一种类型定义,无需联合即可涵盖原始类型和泛型类型的属性
Posted
技术标签:
【中文标题】一种类型定义,无需联合即可涵盖原始类型和泛型类型的属性【英文标题】:One type definition to cover properties of primitive and generic types without unioning 【发布时间】:2017-01-12 13:02:41 【问题描述】:这是需要我定义两种我想重构/整合的类型的模式:
...
.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
);
我想定义 promises
和 resolvedPromises
的类型,但由于它们是类型相关的,我想定义一个类型(可能是泛型)而不是定义具有相似定义的两个类型。
所以而不是:
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>
问题在于,从通常的泛型类型的角度来看,我们提供了要注入的最内层类型,但在我的情况下,我需要以某种方式定义 outer输入 ng.IPromise<>
或实际上什么都没有。
我也不希望最终得到一个允许两种类型的单一类型:
public interface ConsolidatedType
[id: string]: any | ng.IPromise<any>,
one: Something1 | ng.IPromise<Something1>,
two: Something2 | ng.IPromise<Something2>
这将允许在无效的地方进行混合和匹配。所以这是不行的。有没有其他方法可以真正拥有一个没有代码重复的单一类型,只将类型包装到 Promise 中?
【问题讨论】:
我不确定我是否收到您的代码。如果promises
是ResultingType
类型,那么one
和two
不应该是承诺吗?当你给他们分配$q.when(...)
?另外,为什么你将这些接口定义为可索引的(也就是说,为什么你有[id: string]: any
?)
1. 为什么要建立索引? 为了满足$q.all
调用,因为它被定义为all(promises: [id: string]: IPromise<any>; ): IPromise< [id: string]: any; >
,所以基本上我只定义了两个属于同一类型定义的附加预定义属性。
2. one
和 two
是否应该作为结果的 promise? 不。因为我们应该在创建 deferred 时提供 promise,但是当它们被解决时,我们会得到它们的已解决值而不是已解决的承诺。请参阅我之前评论中的$q.all
定义。
【参考方案1】:
怎么样:
interface BaseType<T, S>
[id: string]: T;
one: S;
two: S;
然后:
...
.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
);
您还可以创建“快捷方式”:
interface PromiseType extends BaseType<ng.IPromise<any>, ng.IPromise<Something1>>
interface ValueType extends BaseType<any, Something1>
然后:
...
.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
);
【讨论】:
这是一个可行的解决方案,虽然不是很好,因为我的预定义属性不是同一类型。如果我们有其中两个,我们最终会得到一个具有三个泛型子类型的泛型类型,如果更多它总是 N = exrea 属性的数量,那么我们就有一个具有 N+1 个子类型的泛型类型。以上是关于一种类型定义,无需联合即可涵盖原始类型和泛型类型的属性的主要内容,如果未能解决你的问题,请参考以下文章