【发布时间】:2021-02-20 14:45:39
【问题描述】:
我有一个 Typescript 项目,我在函数内部调用 Date。我想使用与 Date 重载的构造函数相同的函数参数:
interface DateConstructor {
new(): Date;
new(value: number | string | Date): Date;
new(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;
// ...
}
我想使用扩展运算符将参数传递给Date 的构造函数。所以我的函数应该是这样的:
function myFn(...args: DateComponents): Date {
return new Date(...args)
}
在我的情况下,我实际上并没有返回日期,但这只是为了测试......
现在的问题是如何定义DateComponents。我成功地分别实现了DateConstructor的3个重载签名。
// Case A: No argument provided
interface A {
(): Date;
}
const a: A = function (...args: []): Date {
return new Date(...args);
}
// Case B: 1 argument provided
interface B {
(value: number | string | Date): void;
}
const b: B = function (...args: [number | string | Date]): Date {
return new Date(...args);
}
// Case C: Between 2 and 7 arguments provided
interface C {
(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): void;
}
const c: C = function (...args: [number, number, number?, number?, number?, number?, number?]): Date {
return new Date(...args);
}
到目前为止一切顺利,一切正常。
- 答:空元组用于覆盖不传递参数的情况
-
B:一个元素的元组涵盖了传递单个数字、字符串或
Date对象的情况 - C: 包含 2 个强制和 5 个可选数字元素的元组涵盖了传递 2-7 个参数的情况
如果我尝试将这 3 个示例合并为 1 个,我会得到:
interface D {
(): void;
(value: number | string | Date): void;
(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): void;
}
type DateComponents = [] | [number | string | Date] | [number, number, number?, number?, number?, number?, number?];
const d: D = function (...args: DateComponents): Date {
return new Date(...args); // <-- ERROR: Expected 0-7 arguments, but got 0 or more.
}
我收到一条错误消息,指出 Typescript 认为可以将超过 7 个参数传递给 Date 构造函数。我不明白为什么,因为我的类型 DateComponents 明确定义了 0-7 个元素的元组。
我可以通过使用一些条件和类型断言来解决这个问题,但我希望有一个更漂亮的解决方案?
See the code in the Playground here
有办法解决这个问题吗?非常感谢!
【问题讨论】:
-
类型断言是最简单的解决方案
标签: typescript