mlc*_*mlc 5 javascript types bigint typescript
在普通的无类型 JavaScript 中,编写一个可以对数字或 bigint 进行操作的函数并不难,具体取决于传入的参数:
\nconst sumOfSquares = (a,b) => a*a + b*b;\nsumOfSquares(3, 4); // returns 25\nsumOfSquares(3n, 4n); // returns 25n\nsumOfSquares(3n, 4); // throws a TypeError\nRun Code Online (Sandbox Code Playgroud)\n似乎应该有一种方法在打字稿中声明这个函数,以便编译器强制参数一起工作。我试过
\nconst sumOfSquares = <N extends bigint | number>(a: N, b: N): N =>\n a * a + b * b;\nRun Code Online (Sandbox Code Playgroud)\n但编译器拒绝了这一点:
\n\n\n语义错误 TS2322:类型“number”无法分配给类型“N”。
\n
\n\xc2\xa0 \'number\' 可分配给类型 \'N\' 的约束,但 \'N\' 可以使用约束 \'number | 的不同子类型来实例化。bigint\'。
是否有不同的方法来编写类型声明以使其起作用?
\n这是解决方案:
function sumOfSquares<N extends number>(a: N, b: N):N
function sumOfSquares<N extends bigint>(a: N, b: N):N
function sumOfSquares<N extends bigint | number>(a: N, b: N) {
return a * a + b * b;
}
sumOfSquares(2n,2n) // ok
sumOfSquares(2,2) // ok
sumOfSquares(2n,2) // error
sumOfSquares(2,2n) // error
Run Code Online (Sandbox Code Playgroud)
顺便说一句,您还可以定义箭头函数的重载:
interface Overloading {
<N extends number>(a: N, b: N): N
<N extends bigint>(a: N, b: N): N
<N extends bigint | number>(a: N, b: N): N
}
const sumOfSquares: Overloading = <N extends bigint | number>(a: N, b: N) => a * a + b * b;
sumOfSquares(2n, 2n) // ok
sumOfSquares(2, 2) // ok
sumOfSquares(2n, 2) // error
sumOfSquares(2, 2n) // error
Run Code Online (Sandbox Code Playgroud)
如果您将第一个参数作为简单数字传递,TS 将期望第二个参数具有相同的类型。与 BigInt 的行为相同
更新
我应该添加一个额外的泛型才能使其工作。
感谢@jcalz 为我指明了正确的方向:
function sumOfSquares<A extends number, B extends number>(a: A, b: B): number
function sumOfSquares<A extends bigint, B extends bigint>(a: A, b: B): bigint
function sumOfSquares<A extends number | bigint, B extends A>(a: A, b: B): bigint | number {
return a * a + b * b
};
const x = 3n;
let y: number | bigint;
if (Math.random() < 0.5) y = 4;
else y = 4n;
const result = sumOfSquares(x, y) // There should be an error here
const result2 = sumOfSquares(3n, 4) // There should be an error here too
const result3 = sumOfSquares(3, 4n) // There should be an error here too
const result4 = sumOfSquares(3, 4) // ok
const result5 = sumOfSquares(3n, 4n) // ok
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
462 次 |
| 最近记录: |