こんにちは。
ある要件でセンシティブな文字列を扱う必要があり、TypeScriptが提供しているstring型だけでは要件を満たせない場面がありました。
調べてみると、TypeScriptでは変数の型としてより詳細にstring
型を定義する方法があることを知りましたので、その方法を紹介します。
簡単なコード
まずは簡単なコード紹介です。
先頭にスラッシュを入れなければいけない文字列リテラルを定義したいとき、以下のようにすると実現できます。
const hoge: `/${string}` = '/api'; // エラーが出力されない
const hoge2: `/${string}` = 'api'; // エラーが出力される
TypeScript: TS Playground
また、逆にスラッシュを含めてはいけない場合は、以下のようにinferを使って推測し、neverを返す型を定義することで実現できます。
type NonSlashedString<S extends string> = S extends `/${string}` ? never : S;
const hoge: NonSlashedString<'api'> = 'api'; // エラーが出力されない
const hoge2: NonSlashedString<'/api'> = 'api'; // エラーが出力される
const hoge3: NonSlashedString<'api'> = '/api'; // エラーが出力される
ユースケース紹介(Router定義)
これらの方法を使うと、TypeScriptにおいてstring型をより詳細に定義できます。
特に、センシティブな文字列に対して細かな制約をかける際に役立ちます。
例えば、frontから各APIへ接続する際に、APIパスにスラッシュの有無で挙動が変わってしまう場合があります(例:CORSなど)。
このような文字列のスラッシュ有無などのヒューマンエラーは避けることができない場合もあるため、TypeScriptを使用している以上は静的な型チェックを行いたいと考えることでしょう。
以下のように定義することで、入力値に対して厳密なチェックを行うことができ、安全性を向上させることができます。
type NonSlashedString<S extends string> = S extends `/${string}` ? never : S;
type SlashedString = `/${string}`;
export class Router {
public static readonly non_slashed: NonSlashedString<'api/public'> = 'api/public';
public static readonly slashed: SlashedString = '/api/private;
};
TypeScript: TS Playground
NonSlashedStringやSlashedStringなど、型を使って入力値を厳密にチェックすることで、安全性を向上させることができます。
また、型で強制することで他の人が追加する時も安心です。
このように、TypeScriptの型定義における正規表現ライクなstring型の詳細な使い方を紹介しました。
是非、自身のTypeScriptプロジェクトで活用してみてください。