看起来我正在努力做的事情是不可能的,但我真的希望它是。
本质上,我有两个接口,我想将一个函数参数注解为这两个接口的组合。
interface ClientRequest {
userId: number
sessionKey: string
}
interface Coords {
lat: number
long: number
}
然后,在函数中,我想做这样的事情:
function(data: ClientRequest&Coords) { ... }
这样我的'data'对象就可以包含这两种类型的所有成员。
我在spec preview中看到了一些引用,在“组合类型的成员”下,但似乎还没有实现。
如果不可能,我的解决方案可能是这样的:
interface ClientRequest<T> {
userId: number
sessionKey: string
data?: T
}
function(data: ClientRequest<Coords>) { ... }
这在这种情况下是可行的,尽管它不像我希望的那样动态。我真的希望能够在注解本身中合并多个(2+)类型:
function(data: TypeA&TypeB&TypeC) { ... }
我想传统的解决方案是定义一个扩展这些类型的类型,尽管这似乎不太灵活。如果我想添加一个类型,我必须
- (a)回到声明并重写它,或者
- (B)建立一个全新的界面。我不确定我是否同意额外的开销。
有没有TypeScriptMaven愿意为我指出正确的方向?
7条答案
按热度按时间ni65a41a1#
回复更新日期2018-10-30
TypeScript现在有类型交集。所以你现在可以简单地做:
原始答案
对你的问题的具体回答是:不,没有一个内联注解来表示组合或扩展类型。
对于您试图解决的问题,最好的做法是创建第三种类型,以扩展其他两种类型。
jtjikinw2#
如果你使用ES6
Object.assign
,很有可能。假设您已经有了这些类型的对象。首先让我们定义类型
现在两者的结合:
假设你有两个现有的对象,你想传递给函数:
你可以这样合并它们:
或者简单地创建一个新的,像这样:
上一个方法
不是类型安全的。
<Type> {...}
语法将对象转换为尖括号(Type
)中指定的类型,这会绕过Typescript的检查器。见类型Assert。*最后,调用函数:
请参阅另一个问题,了解更多实现此目的的方法:
How can I merge properties of two JavaScript objects dynamically?
q9yhzks03#
接口的答案是一种相当优雅的组合两种结构的方法,但是您提到您想知道是否可以将类型组合为注解的一部分。
接口说明
我已经提供了一些与您的问题相关的功能的描述,但首先我要说的是,如果您因为认为必须创建
ICoords
接口(在您的问题中,它看起来更像是一个类)而推迟了接口解决方案-请放心-因为接口也可以扩展类:只要属性具有相同的名称和类型,接口甚至会合并它们。(例如,如果它们都声明了属性
x: string
。下面是您提到的其他注解特性的注解。
联合类型
你可能读过的规范是union类型,它看起来像这样:
但这只能确保
x
是一个或另一个,而不是两者的组合。据我所知,你的合并类型IClientRequest & Coords
的语法并不在路线图上。这也不是当前版本的一部分,但稍后会发布。
元组类型
您可能已经看到的规范的另一个可能部分是元组类型:
但这会将数据的形状从结构改变为类似于数组的形状,其中元素
0
是IClientRequest
,元素1
是Coords
。Uber-Annotation
最后,如果你真的不想创建一个合并的接口,你可以使用一个uber-annotation:
2fjabf4q4#
这是一个基于this answer的可重用实用程序类型,用于组合
Record
类型的联合Playground example
iqjalb3h5#
现在,如果类型P1和P2扩展了object,你可以用条件类型做这样的事情:
最好的方法是,如果这适用于你的情况,这:
7gcisfzg6#
我在spec preview中看到了一些引用,在“组合类型的成员”下,但似乎还没有实现。
我认为你会对
intersection
类型更感兴趣(而不是union
)。不同之处在于传入的对象必须支持 * 所有 * 属性,而不是 * 其中之一 *。Github问题:https://github.com/Microsoft/TypeScript/issues/1256#issuecomment-64533287
vsikbqxv7#
我只需要这样做,以下解决方案对我有效: