如何在 Typescript 中限制泛型 return 类型?

How to limit generic return type in Typescript?

我想创建一个函数,它会尝试 运行 提供的函数,并且会抛出异常,除非它 returns 是一个真值,就像这样:

function test<T>(runnable: () => T): T {
    const value = runnable();
    if (! value) throw new Error(`Only truthy`);
    return value;
}

const a = test(() => {
    return (Math.random() < 0.5) ? undefined : "ok";
});

console.log(a);

如何更改 test 的定义,以便 TS 知道 a 始终是字符串,而不是 string|undefined

如果您将虚假类型作为内部函数 return 类型的一部分,但 而不是 外部函数类型的一部分,那么这是可能的:

首先,制作一个Falsy类型别名:

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

现在为内部函数 return 与 T 建立联合,类型:

function test<T>(runnable: () => T | Falsy): T {
    const value = runnable();
    if (!value) throw new Error(`Only truthy`);
    return value;
}

这意味着 T 被推断为 包括 Falsy 类型。并且内部 runnable 函数允许 return T 或任何 Falsy 类型。然后检查 Falsy 类型并仅在值不是 Falsy 时才继续 return,这必须是 T.

现在此函数的 return 类型为 "ok",因为该错误会捕获所有其他结果。

const a = test(() => {
    return (Math.random() < 0.5) ? undefined : "ok";
});

a // type: "ok"

Playground