如何在TypeScript界面​​中要求特定的字符串


144

我正在为第三方js库创建TypeScript定义文件。其中一种方法允许使用options对象,而options对象的属性之一则接受列表中的字符串:"collapse","expand","end-expand",和"none"。

我有一个用于options对象的接口:

interface IOptions {
  indent_size?: number;
  indent_char?: string;
  brace_style?: // "collapse" | "expand" | "end-expand" | "none"
}

接口可以强制执行此操作,因此,如果您IOptions在brace_style属性中包含一个对象,它将仅允许可接受列表中的字符串?


4
请重新回答该问题的答案
— Andreas

Kinda遵循@Andreas的评论,为什么您偏爱RyanQ的答案而不是Denis Khay的答案 ?Denis似乎更适用于imo。
— 鲁芬

Answers:


226

它在版本1.8中作为“字符串文字类型”发布。

Typescript的新增功能-字符串文字类型

页面中的示例:

interface AnimationOptions {
  deltaX: number;
  deltaY: number;
  easing: "ease-in" | "ease-out" | "ease-in-out";
}

6
它需要在应用程序中的任何位置复制并粘贴带有字符串的行,您需要将此类型的字符串作为参数传递。如果您始终使用整个AnimationOptions,则该解决方案似乎不错,但对于仅允许使用“缓动”类型的用例来说,这是错误的。看到Denis Khay的答案,它要好得多。
— PatrykWlaź18年

121

试试这个

export type ReadingTypes = 'some'|'variants'|'of'|'strings';

export interface IReadings {
   param:ReadingTypes
}

12
应该将其标记为正确,因为它允许在应用程序中的任何地方重用创建的类型。
— PatrykWlaź18年

这正是我一直在寻找的一种将字符串数组作为值传递给枚举类型的方法。通过完全跳过枚举并使用type,我可以传递以下示例:const myVar: ReadingTypes = ["some"|"variants"];同时仍保持动态枚举键入语法。完全同意,应该将答案标记为正确。
— mdawsondev

有没有办法使用这种方法,但是像这样轻轻地输入,type VisibilityTypes = VISIBILITY.PUBLISH | VISBIBILITY.DRAFT我得到一个找不到命名空间的错误,但是当我对其进行硬编码时,它似乎可以工作
— Max Carroll

我找到了一种方法,并添加了一个新答案
— Max Carroll,

10

也许不是您想要的,但Enum对于您来说似乎是一个完美的解决方案。

enum BraceStyle {Collapse, Expand, EndExpand, None}

interface IOptions {
  indent_size?: number;
  indent_char?: string;
  brace_style?: BraceStyle
}

但是,枚举是基于数字的。这意味着BraceStyle.Collapse在这种情况下,在运行期间,例如,实际值将为0。但是您可以将它们与其他甚至非打字稿脚本一起使用,因为它们可以编译为对象。这是BraceStyle编译运行后的样子:

{
    0: "Collapse",
    1: "Expand",
    2: "EndExpand",
    3: "None",
    Collapse: 0,
    Expand: 1,
    EndExpand: 2,
    None: 3
}

如果你想字符串时,可以使用静态成员类,描述在这里


enum可以具有字符串值(至少现在不确定,是否可以在2014年使用)。enum BraceStyle { Collapse = "Collapse", Expand = "Expand" }。
— ZachB

如果他们能在2014年参加,我会在回答中提及这一点。
— 库巴Jagoda,

8

TS提供了对特定字符串值的输入,这些值称为String文字类型。

这是如何使用它们的示例:

type style =  "collapse" | "expand" | "end-expand" | "none";

interface IOptions {
  indent_size?: number;
  indent_char?: string;
  brace_style1?:  "collapse" | "expand" | "end-expand" | "none";
  brace_style2?:  style;
}

// Ok
let obj1: IOptions = {brace_style1: 'collapse'};

// Compile time error:
// Type '"collapsessss"' is not assignable to type '"collapse" | "expand" | "end-expand" | "none" | undefined'.
let obj2: IOptions = {brace_style1: 'collapsessss'};

1
function keysOf<T>(obj: T, key: keyof T) { return obj[key]; }
interface SomeInterface {
   a: string;
}
const instance: SomeInterface = { a: 'some value'};
let value = keysOf<SomeInterface>(instance, 'b'); // invalid
value =  keysOf<SomeInterface>(instance, 'a'); // valid

1

从TypeScript 2.4开始,您可以使用字符串枚举

我赞成这种方法,因为它避免了在多个地方使用相同的硬编码字符串。

可以在值是字符串的情况下创建一个枚举

export enum VISIBILITY {
  PUBLISH = "publish",
  DRAFT = "draft"
}

然后可以将此枚举用作接口或类上的类型

export interface UserOptions  {
  visibility:  VISIBILITY 
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.