typescript - 如何断言 `number` 类型为正?

标签 typescript typescript-generics

假设我有以下求一个数的平方根的函数:

function sqrt(n: number): number {
    return Math.sqrt(n);
}

我想找到一种方法来断言给定的数字是非负数。目前,Math.sqrt 函数为负数返回 NaN,这可能会引入隐蔽的错误,所以我宁愿在编译时捕获这些简单的错误。当给定的 number 不是正数时,有什么方法可以使 TypeScript 出错?

最佳答案

您可以通过一些字符串内在函数和条件类型来做到这一点。基本上,我们可以为数字取一个泛型,N。然后,通过 ${N} 对该数字类型进行字符串化,并检查该字符串是否以 - 开头,这意味着该数字实际上是负数。如果是这样,我们可以返回 never 以强制 TypeScript 在泛型参数上失败。

type AssertPositive<N extends number> =
  number extends N ? N : `${N}` extends `-${string}` ? never : N;

function sqrt<N extends number>(n: AssertPositive<N>): number {
    return Math.sqrt(n);
}

// No Errors 🎉
sqrt(5);
sqrt(0);
sqrt(1.5);
sqrt(1e3);

// Correctly errors 🎉
sqrt(-5);
sqrt(-1);
sqrt(-3.4);
sqrt(-0.4);

TypeScript Playground Link

数字扩展了 N ? AssertPositive 的 N 子句只是让 AssertPositive 允许非精确数字类型(number)与 sqrt 一起工作 因为无法确定 number 类型是正数还是负数,因为它不提供上下文。

number 类型强制转换 (credits @jcalz)

作为@jcalz mentioned in the comments ,您可能希望在向 sqrt 提供 number 类型时强制进行显式转换。这可以通过品牌类型来完成,品牌类型基本上将一些上下文附加到 number 类型本身。 Here is the playground link @jcalz 创建来展示这种行为。

关于typescript - 如何断言 `number` 类型为正?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71670965/

相关文章:

TypeScript const 和 const with as const

typescript - lib.es2015.promise.d.ts(33, 34) : An argument for 'value' was not provided

javascript - 是否可以将远程 javascript 描述为带有 .d.ts 文件的 typescript 模块?

javascript - react / typescript : How to get json file data

typescript - 使 TypeScript 返回类型取决于是否存在可选属性

typescript - 更窄的类型不能分配给其他类型

typescript - TypeScript 不能确保使用正确的类型解析 Promise 吗?

javascript - typescript 数组声明是否需要展开/休息运算符?

typescript - 如何输入对应类型的元组数组?

typescript - TS - 如何对泛型类型内的类型值执行字符串函数