circumspect
TypeScript/JavaScript コードをより安全にするための関数のセットです。これらの関数には、 invariant
、 warning
、 assertNever
などが含まれます。
invariant
やassertNever
など、コードの安全性を高める便利な関数が多数あります。これらの関数の多くは、個別の npm パッケージ (例: invariant
) として利用できます。しかし、関数ごとに新しいパッケージ (そしてほとんどの場合、対応する@types
パッケージ) をインストールするのはあまり便利ではありません。また、これらのパッケージは通常、関数をデフォルトのエクスポートとしてエクスポートするため、VSCode の自動インポートがうまく機能しません。
このライブラリは、コードをより安全にする関数を 1 か所に統合します。 circumspect
それらすべてを含む単一の依存関係です。また、 circumspect
によって提供されるすべての関数はエクスポートという名前が付けられているため、VSCode の自動インポートは期待どおりに機能します。
さらに、 circumspect
は 100% TypeScript で書かれているため、すべての関数はデフォルトで適切に型付けされます。したがって、個別の@types
パッケージをインストールする必要はありません。
糸の使用:
yarn add circumspect
npm の使用:
npm install circumspect
invariant
warning
assertNever
nonNull
invariant
invariant ( value : unknown , message ?: string ) : asserts value
value: unknown
真実であることを確認したい値です。
message?: string
渡されたvalue
が false の場合にスローされるエラーに含まれるオプションのエラー メッセージです。このカスタム エラー メッセージは開発中にのみ表示されます。運用環境では、代わりに一般的なエラー ( 'Invariant violation'
) が表示され、 message
パラメーターは無視されます。
asserts value
これは、関数が単にvalue
の型を真実になるように絞り込み、何も返さないことを意味します。 invariant
指定されたvalue
が真実であることを保証します。そうでない場合は、指定されたmessage
を含むエラーがスローされます (開発時のみ)。この関数は、すべての偽の値 (例: null
やundefined
) を除外することで、 value
のタイプを適切に絞り込みます。
invariant
偽である可能性がある値を持っている場合には常に使用する必要がありますが、特定の状況では、その値は真実でなければならないと確信しています。つまり、値が真であるという事実は不変条件であり、値が偽である場合は不変条件に違反しているため、エラーをスローする必要があります。
message
引数は運用環境では完全に無視されるため、運用ビルドではコードからメッセージ引数を完全に削除することをお勧めします。その方法については、「最適化」セクションを参照してください。
declare const user : User | null | undefined ;
invariant ( user , 'The user is missing!' ) ;
user ; // If we get here, the type is narrowed to `User`
この例では、 user
オブジェクトは潜在的にnull
またはundefined
(つまり false) になる可能性があります。その場合は、不変条件違反があり、 invariant
関数がスローされます。それ以外の場合は、単に戻り、 user
実際にユーザー オブジェクトを指していることがわかります。
warning
warning ( value : unknown , message : string ) : void
value: unknown
確認したい値です。偽の場合は、コンソールに警告が発行されます。
message: string
コンソールに書き込まれる警告メッセージです。
void
関数は何も返しません。 warning
指定されたvalue
が false の場合、指定されたmessage
とともにコンソールに警告を発行します。警告は開発中にのみ発行されます。運用環境では、この関数は何も行いません。
これは、値が間違っている場合に開発専用の警告を発行する場合に常に使用する必要があります。これは、警告メッセージで報告されている重大ではない問題を開発者が修正できるようにするのに役立ちます。
実稼働環境ではwarning
何も行わないため、実稼働ビルドではコードからこの関数の呼び出しを完全に削除することをお勧めします。その方法については、「最適化」セクションを参照してください。
declare const mode : 'auto' | 'default' | 'slow' | 'fast' ;
warning (
mode !== 'auto' ,
'Mode "auto" has been deprecated. Please use "default" instead.' ,
) ;
この例では、 mode
が'auto'
の場合に非推奨の警告を発行したいと考えています。そのためには、 false の値を渡す必要があります。そのため、 mode !== 'auto'
を渡します。これは、 mode
が'auto'
の場合にのみ false になります。
場合によっては、 false
直接渡すことが合理的です。例えば:
declare const languages : Language [ ] ;
declare const defaultLanguage : Language ;
declare const langName : string ;
let lang = languages . find ( ( { name } ) => name === langName ) ;
if ( ! lang ) {
warning (
false ,
`Language with name " ${ langName } " not found. Falling back to the default language.` ,
) ;
lang = defaultLanguage ;
}
assertNever
assertNever ( value : never ) : never
value: never
考えられる共用体型のバリアントをすべて使い果たした後の値です。 never
、関数が決して戻らないことを意味します。実際に呼び出されるとエラーがスローされるだけです。 共用体型のすべてのバリアントを確実に使い果たすために、 assertNever
使用する必要があります。
value
のすべての共用体バリアントが使い尽くされている場合、 value
を指定してassertNever
を呼び出してもコンパイラ エラーは発生しません。これは、その時点ではvalue
never
型とみなされ、実行時には、 assertNever
呼び出す時点に到達することはありません。エラーはスローされません。
ただし、すべての共用体バリアントが使い尽くされていない場合は、 never
以外の値でassertNever
呼び出しているため、次のようなコンパイラ エラーが発生します。
Argument of type 'x' is not assignable to parameter of type 'never'.
これは、欠落しているバリアントを処理することで修正できます。共用体の網羅性チェックとassertNever
の詳細については、TypeScriptのドキュメントを参照してください。
declare const state : 'loading' | 'done' | 'error' ;
switch ( state ) {
case 'loading' :
return < Loading / > ;
case 'done' :
return < Done / > ;
case 'error' :
return < Error / > ;
}
この例では、 switch
ステートメント内のすべての可能な状態 ( 'loading'
、 'done'
、および'error'
を処理します。
ただし、将来的に'pending'
などの別の状態を追加した場合はどうなるでしょうか?
switch
ステートメントが'pending'
を処理していないという事実は検出されません。
解決策は、すべての可能な状態が処理されたと主張するdefault
ケースを用意することです。
switch ( state ) {
...
default :
return assertNever ( state ) ;
}
したがって、すべての状態バリアントが処理される場合、コンパイル時エラーは発生しません。ただし、新しい'pending'
状態を追加すると、次のようなコンパイラ エラーが発生します。
Argument of type 'string' is not assignable to parameter of type 'never'.
このエラーは、 switch
内で'pending'
状態を処理することで修正できます。
この例からわかるように、 assertNever
考えられるすべてのケースを常に確実に処理する必要があるswitch
ステートメントで特に役立ちます。
nonNull
nonNull < T > ( value : T | null | undefined ) : value is T
value: T | null | undefined
null
またはundefined
でないことを確認する値です。 value is T
これは、関数が渡された値がnull
またはundefined
ないかどうかを示すブール値を返すことを意味します。これにより、 true
が返された場合、 value
の型がT
に絞り込まれます (つまり、 null
とundefined
が除外されます)。 nonNull
は、指定された値が非 null であるかどうか、つまりnull
でもundefined
でもないかどうかをチェックする述語関数です。関数を呼び出した後、返されたtrue
またはfalse
に基づいてvalue
の型が適切に絞り込まれます。
nonNull
、潜在的にnull
、 undefined
、またはその両方である可能性のある値があり、それをチェックしてその型を適切に絞り込みたい場合に使用する必要があります。
この関数の名前は、 NonNullable
ユーティリティ タイプに由来しており、タイプからnull
とundefined
除外します。
declare const names : ( string | null ) [ ] ;
const nonNullNames = names . filter ( nonNull ) ;
// nonNullNames has type 'string[]'
この例では、いくつかのnull
要素も含めることができる名前の配列があります。すべての非 null 要素の配列をフィルターし、 string[]
返します。
代わりにnames.filter(x => x !== null)
を使用すると、null 以外の要素が返されますが、TypeScript はfilter
に渡す関数を認識するため、型は(string | null)[]
のままになります。 boolean
を返すだけなので、型の絞り込みは行われません。
babel-plugin-dev-expression
使用して、 invariant
に渡されるmessage
引数を削除し、本番環境でのwarning
の呼び出しを完全に削除することをお勧めします。
基本的に、運用環境では、 babel-plugin-dev-expression
が
invariant ( value , 'Value is falsy!' ) ;
と
if ( ! value ) {
invariant ( false ) ;
}
したがって、 message
引数は削除されます。また、 warning
への呼び出しも完全に削除されます。したがって、次のような行
warning ( value , 'Value is falsy!' ) ;
が削除されます。
プルリクエストは大歓迎です。大きな変更を導入する場合は、まず関連する問題を開いて、変更したい内容について話し合ってください。
必要に応じてテストと README を更新してください。
マサチューセッツ工科大学