【问题标题】:Typescript: Union Type as interface打字稿:联合类型作为接口
【发布时间】:2017-09-16 21:45:08
【问题描述】:

我有一种情况,我需要一个函数来接受各种不同的类型。它们将由函数内的类型保护分隔。所以我使用这样的联合类型:

function(param: TypeA | TypeB): void {
    let callback: (param: TypeA | TypeB): void = () => {};

    if (isTypeA(param)) {
        callback = doSomethingWithTypeA;
    } else if (isTypeB(param)) {
        callback = doSomethingWithTypeB;
    }

    return callback(param);
}

其中函数doSomethingWithTypeA只接受typeA等等。

如您所见,总是写出(TypeA | TypeB) 非常冗长,尤其是因为在我的实际代码中它不止两种类型。

有没有办法创建一个(TypeA | TypeB) 的接口?
还是有其他方法可以实现这一点?

【问题讨论】:

  • type TypeAorB = TypeA | TypeB ?

标签: typescript types union-types


【解决方案1】:

创建一个接口怎么样:

interface MyType {
}

class TypeA implements MyType {
}

class TypeB implements MyType {
}

然后可以在方法中查看:

function(param: MyType): void {
    let callback: (param: MyType): void = () => {};

    if (param instanceof TypeA) {
        callback = doSomethingWithTypeA;
    } else if (param instanceof TypeB) {
        callback = doSomethingWithTypeB;
    }

    return callback(param);
}

【讨论】:

  • 怎么回事?一个坏主意是让一个函数做不止一件事,但这是个问题……好奇你在上面看到的还有什么不好的?
  • 不,这不是原因。这不是联合类型。它是两个类(顺便暗示了一个重大的接口更改)并且它不支持穷举检查。类型案例不应相互减去,并且类不相关,除了在结构上等价(因为两者都是空的)。创建空类和接口是不好的,因为 TypeScript 具有结构类型,而不是名义类型。您的答案在 Scala 中看起来像 case object,在 TypeScript 中不起作用。此外,implements 100% 不相关。
  • 空类只是指示性的,它们显然具有特定于实现的属性/方法。这不是一个完整的答案,但总的来说,我发现使用接口是一种更好的方法,因为 TypeA 和 TypeB 中可能会有行为,您可以抽象到接口并保存案例检查。但是我来自 C# 背景,并且仍然掌握 Typescript 的做事方式,所以我接受你的观点。
  • 是的,如果您尝试使用 a 作为直觉的基础,C# 背景会导致您误入歧途。接口在打字稿中扮演着不同的角色。这里更好的方法是两个interfaces、AB,没有共同的继承和联合类型创建为type U = A | B
  • 当人们开始学习这种语言时,他们倾向于将类型混为一谈。考虑在 TypeScript 中 a instanceof A 是对两个值的操作,A 不是该表达式中的类型。
【解决方案2】:

使用type aliases:

type YourType = TypeA | TypeB // | ... and so on

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 2015-08-17
    • 2018-12-07
    • 1970-01-01
    • 2017-05-18
    • 2021-08-05
    • 2018-12-06
    • 2020-11-30
    相关资源
    最近更新 更多