typescript - TypeScript 中的联合类型有什么用?

标签 typescript

首先,没有关于使用称为联合类型的 TypeScript 新功能的官方指南(截至 2015 年 3 月 8 日的 AFAIK)。好吧,我试图找到一种自己使用它们的方法。这并不容易。我仍在努力寻找联合类型在我的代码中的位置:

  • 它们不能与接口(interface)一起使用,因为没有可靠的运行时检查来判断一个值是否实现了一个接口(interface)
  • 由于类型推断的问题,它们不能与泛型一起使用:https://github.com/Microsoft/TypeScript/issues/2264

还剩下什么?

  • 混合基元(通过 typeof 解构)
  • 混合类(通过 instanceof 解构)

我认为这 2 种是目前在 TypeScript 中使用联合类型的唯一有效方式是否正确?

如果是,是否有任何计划扩大其适用范围?

如果不是,我错过了什么?

最佳答案

我不认为你能得到一个单一的答案;至少,联合类型处理许多不同的用例,使用户能够以类似于他们编写规范 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
    }
}

CallExpressionTaggedTemplateExpression 都有一个共同的 callTarget,因此您始终可以从 CallLikeExpression< 中获取正在调用的表达式 仅使用 callTarget 属性。

如果您想获得将被馈送到调用中的参数,您可以使用 getEffectiveCallArguments 提取它,它知道如何处理两者之间的差异。

关于typescript - TypeScript 中的联合类型有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28931221/

相关文章:

push-notification - TypeScript 和 Chrome 通知

javascript - 如何从现有对象初始化 typescript 类?

javascript - Typescript 属性装饰器 - 需要帮助以了解以下情况如何发生?

javascript - Angular (Angular 4) RouterLinkActive 用于菜单和子菜单配置

javascript - Visual Studio 2017 : js file causes many typescript errors

javascript - 为什么使用 setTimeout 可以显示图表

javascript - 为什么在带有 Chrome 的 Android 上进行地理定位时,标题保持为 "null"

typescript :将函数的参数约束为与特定类型的值关联的对象的键

typescript - 为什么 Readonly<T> 可分配给 T,而 ReadonlyArray<T> 不可分配给 Array<T>?

javascript - Angular 2 路由器 V3 : No provider exception