为什么我的 TS 布尔覆盖不适用于"任何"或"未知"?



我希望Boolean(truthy)产生一种类型的true而不是Boolean,对于falsy => false也是如此

所以我这样写:

interface BooleanConstructor {
<T extends false | 0 | '' | null | undefined>(value?: T): false;
<T extends Record<any, any> | string | number | true>(value?: T): true;
<T>(value?: T): boolean;
}

工作很好,除了anyunknown。什么好主意吗?

const A = Boolean(42 as any);     // false ??
const B = Boolean(42 as unknown); // boolean
const A2 = Boolean('');           // false
const B2 = Boolean(0);            // false
const C = Boolean(42);            // true
const D = Boolean('hello');       // true
const E = Boolean(true);          // true
const F = Boolean(false);         // false
const G = Boolean(null);          // false
const H = Boolean(undefined);     // false
const I = Boolean([]);            // true
const J = Boolean({});            // true

是一个带有局部函数的游乐场,但还是一样的。

Boolean(42 as any)可以匹配任何重载(因为any可以匹配任何重载),所以它将先解决哪个重载。如果你交换过载秩序,你会得到true代替false

关于一个可能有效的hack,参见这个playground。基本上,您需要一个新的重载,其中T首先查找与任何其他重载不匹配的类型,例如:

interface BooleanContstructor {
<T extends { [`@hopefully-this-long-string-will-never-be-used-as-a-property`]: {} }>(value: T): boolean
// ...

或者,这样做

最新更新