我正在尝试为我正在使用的矢量数学库创建一个global.d.ts
文件。有一些函数可以采用不同的参数集。例如:
function add(x, y, returnNew) {
if (typeof x != 'number') {
returnNew = y;
if (isArray(x)) {
y = x[1];
x = x[0];
} else {
y = x.y;
x = x.x;
}
}
x += this.x;
y += this.y;
if (!returnNew) {
return this.set(x, y);
} else {
// Return a new vector if `returnNew` is truthy
return new (this.constructor)(x, y);
}
}
和文档将其描述为
add(x, y [, returnNew]) or
add(array, [, returnNew]) or
add(vec2 [, returnNew])
它总是返回一个矢量对象
如何定义这种类型或接口以匹配此行为?
我尝试过
type addFunction = (
((x: number, y: number, returnNew?: boolean) => Vec2) |
((vec: Vec2, returnNew?: boolean) => Vec2) |
((pos: [number, number], returnNew?: boolean) => Vec2)
)
并且没有错误,但是当我使用它
vector.add(2, 4)
它抱怨Argument of type '2' is not assignable to parameter of type 'number & Vec2 & [number, number]'
我想念什么?请注意,这是第三方库,我只能输入内容,不能触摸库代码。
答案 0 :(得分:2)
您定义的是函数签名的并集。这与带有重载的函数不同。函数的并集意味着实现的函数可以具有这些签名中的任何一个,但不能具有全部签名。这就是为什么在调用参数时必须与所有参数兼容的原因,因为该参数对于任何可能分配的功能都应该有效。
带有重载的函数签名的语法略有不同:
type addFunction = {
(x: number, y: number, returnNew?: boolean): Vec2
(vec: Vec2, returnNew?: boolean): Vec2
(pos: [number, number], returnNew?: boolean): Vec2
}
相交而不是并集也将充当重载签名:
type addFunction = (
((x: number, y: number, returnNew?: boolean) => Vec2) &
((vec: Vec2, returnNew?: boolean) => Vec2) &
((pos: [number, number], returnNew?: boolean) => Vec2)
)
答案 1 :(得分:0)
Typescript中的函数重载有效,但是您必须检查手动使用了哪些重载。因此,以您的示例为例...
function add(array: [number, number], returnNew?: boolean);
function add(vec2: { x: number, y: number }, returnNew?: boolean)
function add(x: number, y: number, returnNew?: boolean);
function add(
param1: [number, number] | { x: number, y: number } | number,
param2?: number | boolean,
param3?: boolean) {
if (Array.isArray(param1)) {
// overload 1
}
else if (typeof param1 === 'object') {
// overload 2
}
else {
// overload 3
}
}