web-dev-qa-db-ja.com

非偽り、別名真実のタイプ

TypeScriptには、真実のタイプはありますか?

私はこのメソッドを持っています:Object.keys(lck.lockholders).length; enqueue(k:any、obj ?: any):voidところで、TSでは空の文字列 ''をチェックする方法があると思います。そして私はそれを次のように変換したいです:

  enqueue(k: Truthy, obj?: any): void

truthyの型を定義する方法がわからない場合を除きます。 I ところで、空の文字列 ''をチェックする方法があると思います

これが必要な理由は、ハッシュのキーとしてnullundefined''などをユーザーに渡したくないためです。

14
user7898461

なぜこれが必要なのかはわかりませんが、興味深いです。正直なところ、短い答えは次のとおりです。TypeScriptはこれに対応していないため、ランタイムチェックを実行してコードを文書化し、kパラメータが真であることを開発者が認識できるようにした方がよいでしょう。それでも、TypeScriptにこのようなことを強制することを試みようとしている場合は、以下をお読みください。


注:以下を機能させるには、strictNullChecksコンパイラオプションをオンにします。 Truthyと_Truthy | null | undefined_を区別できないことが問題になるため、これは必要です。

あなたはほぼを定義することができます falsy 、これは

_type Falsy = false | 0 | "" | null | undefined 
_

ただし、NaNは偽であり、TypeScript を持っていませんNaNの数値リテラルです。

上記のようにFalsyがあっても、TypeScriptには negated types がないため、Truthyを "Falsy以外のすべてのものとして表現する方法はありません。 」.

Use conditional types を使用してenqueue()の誤ったパラメーターを除外することもできますが、奇妙です:

_type DefinitelyTruthy<T> =
  false extends T ? never :
  0 extends T ? never :
  "" extends T ? never :
  null extends T ? never :
  undefined extends T ? never :
  T

declare function enqueue<T extends number | string | true | object>(
  k: T & DefinitelyTruthy<T>,
  obj?: any
): void

declare const str: string;
enqueue(str); // error, might be falsy
enqueue("a"); // okay
enqueue(1); // okay
enqueue(0); // error
enqueue(NaN); // error
enqueue(true); // okay
enqueue(false); // error
enqueue([]); //okay
enqueue({a: "hello"}); // okay
enqueue({}); // error, interpreted as type {} which could be an empty string:
const zilch = "" as {};
enqueue(zilch); // error, see? 
_

mightが偽物であると考えているものを許可しないことに注意してください。これはおそらく達成しようとしていることです。わかりません。


更新

質問を編集して、kパラメータが本当にstring(またはsymbol)である必要があり、除外する必要がある唯一の値が空であることを明確にしたようです。文字列_""_。その場合は、上記を次のように簡略化できます。

_type DefinitelyNotEmptyString<T> = "" extends T ? never : T

declare function enqueue<T extends string | symbol>(
  k: T & DefinitelyNotEmptyString<T>,
  obj?: any
): void

enqueue(""); // error
enqueue("a"); // okay
_

これらはすべてすばらしいですが、残念ながら、一般的なstringenqueue()に渡すと失敗し、場合によっては、使用している値の場合、開発者がそうする必要があるという問題があります。 kパラメータは、指定した文字列リテラルではありません。

_declare const str: string; // comes from somewhere else
enqueue(str); // error!  how do I do this?
_

これに対処するには、値が空かどうかがチェックされたことをコンパイラーに識別させるために使用できる nominal type を作成し、次に ser-defined typeを作成します。 guardstringをそのタイプに制限するには:

_type NotEmptyString = string & {"***NotEmptyString***": true};
function notEmptyString(x: string): x is NotEmptyString {
  return x !== "";
}
_

これで開発者はこれを行うことができます:

_declare const str: string;
enqueue(str); // error, might be falsy
if (notEmptyString(str)) {
  enqueue(str); // okay, str is NotEmptyString
}
_

ふew!それはたくさんのフープジャンプです。これに価値があると思うかどうかはあなた次第です。さて、それが役に立てば幸いです。幸運を!

15
jcalz

Truthyタイプはありません、[〜#〜] [〜#〜]タイプガードシステムを利用できます( タイプ述語 )TypeScriptが実際にtruthyを理解し、それに割り当てるtruthyタイプを支援します!

Falsyタイプと genericisTruthy関数を定義しましょう:

type Falsy = false | 0 | '' | null | undefined;

// this is a type predicate - if x is `truthy`, then it's T
const isTruthy = <T>(x: T | Falsy): x is T => !!x;

これでout isTruthy関数を使用してtruthy値を見つけることができ、TypeScriptは"truthy"タイプを結果に正しく割り当てます。

例:

{   // removing boolean "false" type
  const result: string | false = Math.random() > 0.5 ? 'a' : false;
  const truthyResult: string = isTruthy(result) ? result : 'was false';
}
{   // filtering only numbers from array
  const result: (number | undefined)[] = [42, undefined, 8, 16];
  const truthyResult: number[] = result.filter(isTruthy);
}
{   // filtering only Promises from array
  const result: (Promise<string> | null)[] = [Promise.resolve('a'), null, Promise.resolve('b'), Promise.resolve('c')];
  const truthyResult: Promise<string>[] = result.filter(isTruthy);
}

1
icl7126