Cách yêu cầu một chuỗi cụ thể trong giao diện TypeScript


144

Tôi đang tạo tệp định nghĩa TypeScript cho thư viện js của bên thứ 3. Một trong những phương pháp cho phép một đối tượng tùy chọn, và một trong những thuộc tính của đối tượng lựa chọn chấp nhận một chuỗi từ danh sách: "collapse", "expand", "end-expand", và "none".

Tôi có một giao diện cho các đối tượng tùy chọn:

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

Giao diện có thể thực thi điều này không, vì vậy nếu bạn bao gồm một IOptionsđối tượng với thuộc brace_styletính, nó sẽ chỉ cho phép một chuỗi nằm trong danh sách có thể chấp nhận?


4
Vui lòng xem lại câu trả lời cho câu hỏi này
Andreas

Có những dòng bình luận từ @Andreas, tại sao bạn thích câu trả lời của RyanQ hơn của Denis Khay ? Denis 'dường như áp dụng rộng rãi hơn imo.
ruffin

Câu trả lời:


226

Điều này đã được phát hành trong phiên bản 1.8 dưới dạng "kiểu chữ theo chuỗi"

Có gì mới trong Bản thảo - Các kiểu chữ

Ví dụ từ trang:

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

6
Nó yêu cầu sao chép và dán dòng với các chuỗi bất cứ nơi nào trong ứng dụng mà bạn sẽ cần để vượt qua chuỗi loại này làm đối số. Nếu bạn luôn sử dụng toàn bộ AnimationOptions thì giải pháp đó có vẻ ổn, nhưng đối với các trường hợp sử dụng khi bạn chỉ có thể vượt qua loại 'nới lỏng' thì đó là sai. Xem câu trả lời của Denis Khay, nó tốt hơn nhiều.
Patryk Wlaź

121

Thử cái này

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

export interface IReadings {
   param:ReadingTypes
}

12
Điều này nên được đánh dấu là chính xác, bởi vì nó cho phép sử dụng lại loại đã tạo ở bất cứ đâu trong một ứng dụng.
Patryk Wlaź

Đây chính xác là những gì tôi đang tìm kiếm như là một cách để truyền một mảng các chuỗi dưới dạng các giá trị sang một kiểu liệt kê. Bằng cách bỏ qua enum hoàn toàn và sử dụng type, tôi có thể vượt qua ví dụ sau: const myVar: ReadingTypes = ["some"|"variants"];trong khi vẫn duy trì cú pháp gõ enum động. Hoàn toàn đồng ý rằng điều này đáng lẽ phải là câu trả lời được đánh dấu là chính xác.
mdawsondev

Có cách nào để sử dụng cái này nhưng gõ nhẹ như thế này type VisibilityTypes = VISIBILITY.PUBLISH | VISBIBILITY.DRAFTTôi nhận được một không gian tên không tìm thấy lỗi, tuy nhiên khi tôi cứng mã thì nó dường như hoạt động
Max Carroll

Tôi tìm thấy một cách, và thêm một câu trả lời mới
Max Carroll

10

Có thể không chính xác những gì bạn muốn, nhưng Enumdường như là một giải pháp hoàn hảo cho bạn.

enum BraceStyle {Collapse, Expand, EndExpand, None}

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

Enums, tuy nhiên, dựa trên số. Nó có nghĩa là trong thời gian chạy, giá trị thực cho ví dụ BraceStyle.Collapsesẽ là 0 trong trường hợp này. Nhưng bạn có thể sử dụng chúng với các tập lệnh khác, thậm chí không phải là bản thảo, vì chúng biên dịch thành các đối tượng. Đây là cách BraceStylesẽ chăm sóc biên dịch & chạy:

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

Nếu bạn muốn chuỗi thay thế, bạn có thể sử dụng một lớp với các thành viên tĩnh, như được mô tả ở đây


enums có thể có các giá trị chuỗi (ít nhất là bây giờ, không chắc chúng có thể vào năm 2014 không). enum BraceStyle { Collapse = "Collapse", Expand = "Expand" }.
ZachB

Nếu họ có thể vào năm 2014, tôi sẽ đề cập đến điều đó trong câu trả lời của tôi.
Kuba Jagoda

8

TS cung cấp một kiểu gõ vào các giá trị chuỗi cụ thể, được gọi là kiểu chuỗi ký tự .

Dưới đây là một ví dụ về cách sử dụng chúng:

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

Trong TypeScript 2.4 trở đi, bạn có thể sử dụng String Enums

Tôi ủng hộ cách tiếp cận này vì nó tránh được sự cần thiết phải có cùng một chuỗi mã hóa cứng ở nhiều nơi.

Có thể tạo enum trong đó các giá trị là chuỗi

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

Enum này sau đó có thể được sử dụng như một loại trên giao diện hoặc lớp

export interface UserOptions  {
  visibility:  VISIBILITY 
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.