类型为非虚假,又名真实

时间:2018-07-17 21:13:52

标签: typescript tsc

在TypeScript中,是否有类型?

我有这种方法: Object.keys(lck.lockholders).length;       入队(k:任何,obj ?:任何):无效  顺便说一下,用TS可以找到一种检查空字符串”的方法。 我想将其转换为:

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

除了我不知道如何为Truthy定义类型。我用TS认为,有一种方法可以检查空字符串”。

我想要这样做的原因是因为我不希望用户将nullundefined''等作为哈希的键来传递。

2 个答案:

答案 0 :(得分:13)

我不确定您为什么需要这样做,但这很有趣。坦率地说,简而言之,答案是:TypeScript不适合此操作,您最好进行运行时检查和记录代码,以使开发人员意识到k参数应该是真实的。不过,如果您打算尝试强制TypeScript做类似的事情,请继续阅读:


注意:要使以下各项正常工作,请打开strictNullChecks编译器选项。这是必要的,因为无法将TruthyTruthy | null | undefined区别开来。

您可以几乎定义falsy,就像

type Falsy = false | 0 | "" | null | undefined 

除了NaN也是虚假的,而TypeScript doesn't haveNaN的数字文字。

即使您具有上述的Falsy,TypeScript中也没有negated types,因此也无法将Truthy表示为“除Falsy外的所有内容”。

您可以尝试使用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? 

请注意,它如何不允许它认为可能虚假的任何东西,这可能就是您要实现的目标。无法分辨。


更新

我看到您编辑了问题,以澄清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

所有这些都很棒,但是不幸的是,如果将通用的string传递给enqueue()会失败,并且有时开发人员可能需要这样做,如果他们使用的值是因为k参数不是他们指定的字符串文字:

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

要解决此问题,您可以尝试创建一个nominal type,该代码可用于向编译器标识已检查空值的值,然后制作一个user-defined type guard来约束{ {1}}类型:

string

现在,开发人员可以执行以下操作:

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

哇!跳很多圈。如果您认为这是值得的,则取决于您。好的,希望对您有所帮助。祝你好运!

答案 1 :(得分:0)

没有Truthy类型,但是,您可以利用类型保护系统(type predicate)帮助TypeScript理解真正的truthy并为其进行分配truthy类型!

让我们定义Falsy类型和generic isTruthy函数:

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;

现在,我们可以使用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);
}