TypeScriptインターフェースで特定の文字列を要求する方法


144

サードパーティのjsライブラリ用のTypeScript定義ファイルを作成しています。方法の一つは、オプションのオブジェクトを可能にし、オプションのオブジェクトのプロパティのうちの1つはリストから文字列を受け取り:"collapse"、"expand"、"end-expand"、と"none"。

オプションオブジェクトのインターフェイスがあります。

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

インターフェイスがこれを強制できるのでIOptions、brace_styleプロパティを持つオブジェクトを含める場合、許容リストにある文字列のみが許可されますか?


4
この質問への回答をもう一度ご覧ください
— Andreas

@Andreasからのコメントの行に沿ってちょっと、なぜあなたはデニス・ケイの答えよりもライアンQの答えを好む のですか?Denisの方がより広く適用できるようです。
— ルフィン

回答:


226

これは「文字列リテラル型」としてバージョン1.8でリリースされました

Typescriptの新機能-文字列リテラル型

ページの例:

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

6
アプリでこのタイプの文字列を引数として渡す必要がある場合は、文字列を含む行をコピーして貼り付ける必要があります。常にAnimationOptions全体を使用している場合、そのソリューションは問題ないようですが、「イージング」タイプのみを渡す可能性があるユースケースの場合、これは誤りです。Denis Khayの回答を参照してください。はるかに優れています。
— PatrykWlaź2018

121

これを試して

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

export interface IReadings {
   param:ReadingTypes
}

12
これにより、作成されたタイプをアプリケーションの任意の場所で再利用できるため、正しいものとしてマークする必要があります。
— PatrykWlaź2018

これはまさに、文字列の配列を列挙型に値として渡す方法として探していたものです。enumを完全にスキップしてを使用typeすることで、次の例を渡すことができましたconst myVar: ReadingTypes = ["some"|"variants"];。動的なenum入力構文を維持したままです。これが正解としてマークされた答えであることに完全に同意しました。
— 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
}

代わりに文字列が必要な場合は、ここで説明するように、静的メンバーを持つクラスを使用できます


enumsは文字列値を持つことができます(少なくとも、2014年には可能かどうかは不明です)。enum BraceStyle { Collapse = "Collapse", Expand = "Expand" }。
— ZachB

彼らが2014年にできたなら、私は私の答えでそれを言及します。
— Kuba Jagoda

8

TSは、文字列リテラル型と呼ばれる特定の文字列値への型付けを提供します。

これらの使用例は次のとおりです。

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 
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.