我不确定你为什么需要这个,但它很有趣。老实说,简短的回答是:TypeScript 不适用于此,您最好进行运行时检查并记录您的代码,以便开发人员知道k 参数应该是真实的。不过,如果您打算强制 TypeScript 执行此类操作,请继续阅读:
注意:要使以下内容正常工作,请打开strictNullChecks 编译器选项。这是有必要的,因为无法区分 Truthy 和 Truthy | null | undefined 将是一个问题。
你可以几乎定义falsy,就像
type Falsy = false | 0 | "" | null | undefined
除了NaN 也是假的,TypeScript 没有NaN 的数字文字(请参阅microsoft/TypeScript#15135)。
即使您有上述Falsy,TypeScript 中也没有否定类型(请参阅microsoft/TypeScript#4196),因此无法将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() 它将失败,有时开发人员可能需要这样做,如果他们用于 @987654347 的值@ 参数不是他们指定的字符串文字:
declare const str: string; // comes from somewhere else
enqueue(str); // error! how do I do this?
为了解决这个问题,您可以尝试创建一个nominal type,您可以使用它来向编译器标识一个值已被检查为空,然后创建一个user-defined type guard 来约束一个string类型:
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
}
哇!这是很多箍跳。如果您认为这是值得的,这取决于您。好的,希望有帮助。祝你好运!