Typescript字符串文字联合类型

时间:2017-11-15 16:24:18

标签: typescript

我有一个类属性,其类型是多个字符串文字的并集:

toBinary

我要做的是将这些字符串定义在某种数组中的其他位置,然后在属性定义中使用该数组。如下所示:

public reaction? : 'haha' | 'wow' | 'angry' | 'sad' | 'like';

我知道以上是不可能的,但这是一般的想法。打字稿能提供完成这项工作的任何东西吗?

5 个答案:

答案 0 :(得分:1)

不,您无法为数组中的字符串定义有效值,并在编译时检查它。

当您通过TypeScript编译器运行第一个示例时,其原因变得更加明显 - 它来自:

class Test {
    public reaction?: 'haha' | 'wow' | 'angry' | 'sad' | 'like' = 'haha';
}

对此:

var Test = (function () {
    function Test() {
        this.reaction = 'haha';
    }
    return Test;
}());

编译器运行完毕后,您的类型不再存在了!它只是JavaScript,除了你明确写的内容之外没有添加额外的逻辑。您无法将有效值存储在数组中,因为在代码实际运行之前,不会对数组的内容进行求值,此时已执行类型检查并且已丢弃类型。 / p>

因此,如果要检查字符串是否与数组中的值匹配,则需要实际编写一些在运行时进行检查的代码。

答案 1 :(得分:1)

这取决于您打算如何使用它,但字符串枚举可能会为您提供所需内容:

enum ReactionKind {
    haha = 'haha',
    wow = 'wow',
    angry = 'angry',
    sad = 'sad',
    like = 'like'
}

const reaction: ReactionKind = ReactionKind.angry;

// Get the string value  
const stringValue = ReactionKind[reaction];

// Get the Enum from a string
const enumValue = ReactionKind['wow'];

您仍然可以在需要的地方使用纯字符串值,但您可以将其用作类型和运行时值,这似乎就是您所追求的。

您还会注意到,对于字符串枚举,如果在映射到枚举时使用字符串键,只要您使用--noImplicitAny,就会检查它。

// Error
const enumValue = ReactionKind['wat'];

答案 2 :(得分:1)

自TypeScript 3.4起,您可以使用 const断言从运行时值生成类型。

const allowedStrings = ['haha', 'wow', 'angry', 'sad', 'like'] as const;
type AllowedString = typeof allowedStrings[number]; // [number] is important here

// We can freely map over values
const mapped = allowedStrings.map((s) => s.toUpperCase());

// And use generated type to create type-safe functions
const process = (s: AllowedString) => {
  // Type of s is
  //    s: "haha" | "wow" | "angry" | "sad" | "like"
  return s;
};

答案 3 :(得分:0)

enum Reaction {
    'haha',
    'wow',
    'angry',
    'sad',
    'like'
}

let reaction: keyof typeof Reaction;
reaction = 'angry'; // Fine
// reaction = 'whatever'; // Error

看来上面应该做你想做的。如果仍然需要字符串数组,则可以按以下方式获取它:

const allowedStrings = Object.keys(Reaction).filter(k => Number.isNaN(+k));

答案 4 :(得分:0)

您可以使用 type 来命名联合类型。

type Reaction = 'haha' | 'wow' | 'angry' | 'sad' | 'like';
const reaction?: Reaction = 'haha';