首先,没有关于使用TypeScript的新功能(称为联合类型)的官方指南(截至2015年3月8日的AFAIK)。好吧,我试图找到一种自己使用它们的方法。这并不容易。我仍在努力为我的代码中的联合类型找到一个位置:
还剩下什么?
我认为那些2是目前在TypeScript中使用联合类型的唯一有效方法吗?
如果是的话,有没有计划延长其适用性?
如果不是,我错过了什么?
答案 0 :(得分:2)
我不认为你可以得到一个答案;至少,联合类型处理许多不同的用例,使用户能够以类似于编写规范JavaScript的方式编写TypeScript。无论如何,这是试图解释的。
当你有两种结构上(理想情况下)功能相似的类型时,一个好处就是你可以使用它们共享的属性作为抽象点。
如果您有两种类型不相似的类型,但它们的信息可以如何处理,则可以将函数用于将该信息规范化为常见的抽象形式。
例如,ES6标记模板与调用表达式非常相似:
f `hello ${ 123 } ${ 456 } world!`
以上标记的模板涉及类似于以下内容:
var _t = ["hello ", " ", " world!"];
_t.raw = ["hello ", " ", " world!"];
f(_t, 123, 456);
你可以想象在编译器中,如果它们在方便的时候可以被同等对待来调用表达式,那么它们将是理想的,但是当两者足够清楚时特别处理它们。让我们尝试对此进行建模:
interface TemplateExpression extends Expression {
// ...
}
interface TaggedTemplateExpression extends Expression{
callTarget: Expression;
template: TemplateExpression;
}
interface CallExpression extends Expression {
callTarget: Expression;
arguments: Expression[];
}
type CallLikeExpression = CallExpression | TaggedTemplateExpression;
function getEffectiveCallArguments(expr: CallLikeExpression): Expression[] {
if (expr.kind === SyntaxKind.CallExpression {
// ...
}
else {
// ...
}
// OR, if you don't want to have a tag,
// you could check expr's properties
if ((<CallExpression>expr).arguments) {
// treat as CallExpression
}
else {
// treat as TaggedTemplateExpression
}
}
CallExpression
和TaggedTemplateExpression
共有一个callTarget
,因此您只需使用CallLikeExpression
即可始终从callTarget
调用表达式属性。
如果你想获得将被调用的参数,你可以使用getEffectiveCallArguments
提取它,它知道如何处理两者之间的差异。