【问题标题】:TypeScript: Interface or type for one of constants or stringTypeScript:常量或字符串之一的接口或类型
【发布时间】:2019-03-20 16:09:38
【问题描述】:

我正在使用 TypeScript 来开发我的应用程序。我正在尝试创建一个接口(或类型),它是几个常量之一或随机字符串。

描述我正在尝试构建的伪代码:

contants.ts:

export const ERROR_A = "Error A";
export const ERROR_B = "Error B";
export const ERROR_C = "Error C";

types.ts:

type SWITCH_ERROR = ERROR_A | ERROR_B | ERROR_C | string

我知道这样每个字符串都可能是错误的。我之所以要这样做,是为了可以轻松维护代码库,并且每个已知错误都有它的类型。稍后将在 switch 语句中处理该错误,如下所示:

switchExample.ts:

export const someFunc(error: SwitchError): void => {
  switch(error) {
    case ERROR_A:
      // Do something
    // ... continue for each error.
    default:
      // Here the plain string should be handled.
  }
}

问题是我尝试这样做:

import { ERROR_A } from "./some/Path";

export type SwitchError = ERROR_A;

但这会引发错误:

[ts] Cannot find name 'ERROR_A'.

我做错了什么?如何在 TypeScript 中设计这样的东西?或者这是糟糕的设计?如果是的话,我还能怎么做?

【问题讨论】:

    标签: typescript typescript-typings typescript-types


    【解决方案1】:

    错误是因为您只将ERROR_A 定义为一个值,但您试图将其用作一个类型。 (错误消息没有帮助;我最近提交了an issue 来改进它。)要将每个名称定义为值和类型,您可以在constants.ts 中使用以下内容:

    export const ERROR_A = "Error A";
    export type ERROR_A = typeof ERROR_A;
    export const ERROR_B = "Error B";
    export type ERROR_B = typeof ERROR_B;
    export const ERROR_C = "Error C";
    export type ERROR_C = typeof ERROR_C;
    

    Hayden Hall 的使用枚举的建议也很好,因为枚举成员被自动定义为名称和类型。但是你可以避免所有这些,只写type SWITCH_ERROR = string;当 ERROR_AERROR_BERROR_C 是特定字符串时,它等效于 type SWITCH_ERROR = ERROR_A | ERROR_B | ERROR_C | string

    【讨论】:

    • 首先,好问题!我希望这能得到解决。您可能想在您的线程中添加这个问题作为进一步的证据。其次,感谢您的帮助。正如我在Hayden's answer 上评论的那样,开关盒由于某种原因没有捕获枚举。所以我想没有很好的方法可以使用 TypeScript 来解决这个问题。我可能会像在常规 JavaScript 中一样使用字符串和常量。
    【解决方案2】:

    以下内容应该可以解决问题(假设您的错误是一个字符串):

    enum Errors {
        ERROR_A = 'Error A',
        ERROR_B = 'Error B',
        ERROR_C = 'Error C',
    }
    
    function handleError(error: string) : void {
      switch(error) {
        case Errors.ERROR_A:
          // Handle ERROR_A
        case Errors.ERROR_B:
          // Handle ERROR_B
        case Errors.ERROR_C:
          // Handle ERROR_C
        default:
          // Handle all other errors...
      }
    }
    

    【讨论】:

    • 这个我试过了,还是不行。错误案例只是失败,默认案例总是被调用。
    • 似乎对我有用...见here
    猜你喜欢
    • 2021-07-06
    • 2016-07-17
    • 2016-04-05
    • 2019-07-19
    • 2018-07-14
    • 2020-11-04
    • 2018-09-01
    • 2019-03-11
    • 2019-09-24
    相关资源
    最近更新 更多