简体   繁体   English

在打字稿中定义全新类型的最佳做法?

[英]Best practices for defining an entirely new type in typescript?

I have an execution environment with several constants globally: 我有一个在全局范围内具有多个常量的执行环境:

TOP = 1
TOP_RIGHT = 2
RIGHT = 3
BOTTOM_RIGHT = 4
BOTTOM = 5
BOTTOM_LEFT = 6
LEFT = 7
TOP_LEFT = 8

It is clear to me that these 8 constants are not just arbitrary constants, but actually a set of directions. 对我来说很明显,这8个常量不仅是任意常量,而且实际上是一组方向。 Therefore, I would like to have them be of the DIRECTION type, so that I can do things like this: 因此,我希望它们是DIRECTION类型的,以便可以执行以下操作:

let test: DIRECTION = TOP_LEFT;
let foo: DIRECTION = TOP;
let bar: DIRECTION = LEFT;
let target: DIRECTION = RIGHT;

I've considered several options for how to make this happen (ie what to put in the direction.d.ts file): 我已经考虑了几种方法来实现此目的(即将什么内容放入direction.d.ts文件中):

  1. enum s require a ton of syntax & boilerplate to just get off the ground, so they are undesirable in this case. enum需要大量的语法和样板内容,因此在这种情况下,它们是不可取的。
  2. When I use the type keyword, it seems unable to create a new type that is not simply an alias of another. 当我使用type关键字时,似乎无法创建不仅仅是其他别名的新类型。 (eg type DIRECTION=integer; is allowed, but type DIRECTION; is not. Defining DIRECTION as an alias of integer is undesirable because, despite the fact that they are technically integers in the environment, BOTTOM-2 is nonsensical, and should cause an error. (例如, type DIRECTION=integer;允许,但type DIRECTION;不允许。将DIRECTION定义为整数的别名是不可取的,因为尽管实际上在环境中它们是整数,但BOTTOM-2却是无意义的,并且会导致错误。
  3. interface DIRECTION {} seems to result in the desired behavior, letting me define this new type. interface DIRECTION {}似乎导致了预期的行为,让我定义了这种新类型。 However, it seems like quite an abuse of the typing system (I am under the impression that TS's interfaces were basically the equivalent of classes.) 但是,这似乎是对类型系统的一种滥用(我的印象是TS的接口基本上等同于类。)

What's the most TS-friendly way to accomplish this? 实现此目标的最适合TS的方法是什么?

You can use const and type for this: 您可以为此使用consttype

const TOP = 1
const TOP_RIGHT = 2
type DIRECTION = 1 | 2

let x: DIRECTION = TOP

However, I believe enum is a better solution for this purpose. 但是,我相信enum可以更好地解决此问题。

For example, this is valid but not desirable: 例如,这是有效的,但不是期望的:

const ONE = 1
let x: DIRECTION = ONE

In reference to solution #1, as originally posted: 关于最初发布的解决方案#1:

declare const enum Direction {
    TOP = 1,
    TOP_RIGHT = 2,
    RIGHT = 3,
    BOTTOM_RIGHT = 4,
    BOTTOM = 5,
    BOTTOM_LEFT = 6,
    LEFT = 7,
    TOP_LEFT = 8
}
declare const TOP=Direction.TOP
declare const TOP_RIGHT=Direction.TOP_RIGHT
declare const RIGHT=Direction.RIGHT
declare const BOTTOM_RIGHT=Direction.BOTTOM_RIGHT
declare const BOTTOM=Direction.BOTTOM
declare const BOTTOM_LEFT=Direction.BOTTOM_LEFT
declare const LEFT=Direction.LEFT
declare const TOP_LEFT=Direction.TOP_LEFT

In reference to idea #3, as posted above: 参考上面发布的想法3:

interface DIRECTION {}

declare const TOP: DIRECTION;
declare const TOP_RIGHT: DIRECTION;
declare const RIGHT: DIRECTION;
declare const BOTTOM_RIGHT: DIRECTION;
declare const BOTTOM: DIRECTION;
declare const BOTTOM_LEFT: DIRECTION;
declare const LEFT: DIRECTION;
declare const TOP_LEFT: DIRECTION;

This code is significantly more concise than the solution with enum . 该代码比enum的解决方案更加简洁。

I am still looking for ways to improve it, however, so suggestions/changes are welcome. 我仍在寻找改善的方法,因此欢迎提出建议/更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM