有没有一种方法可以定义 TypeScript 类型,其中只有采用单个 object 参数的函数才能分配给它?例如:
type RestrictToObjectParam = any; // TODO
let fun: RestrictToObjectParam;
fun = (arg: object) => {}; // OK
fun = (arg: {}) => {}; // OK
fun = (arg: {str: string}) => {}; // OK
fun = (arg: {obj: {}, num: number}) => {}; // OK
fun = (arg: number) => {}; // ERROR
像
(arg: object) => any
这样的东西将不起作用,因为第三个示例不可分配给它。我尝试过其他事情,例如:
<T extends object>(arg: T) => any
约束参数类型T extends object ? (arg: T) => void : never
分配参数类型但这些似乎都归结为
(arg: object) => any
。
这可能吗?我可能会误解 TypeScript 中函数类型的一般工作方式。
这是由比较函数类型时的函数参数双方差造成的。在
strictFunctionTypes
模式下,编译器选项 true
默认为
strict
,但您可以将其设置为 false
以实现所需的兼容性行为 — 但是,请注意文档中的警告:
函数参数双方差
比较函数参数类型时,如果源参数可分配给目标参数,则分配成功,反之亦然。这是不合理的,因为调用者最终可能会得到一个采用更专业化类型的函数,但会使用不太专业化的类型调用该函数。实际上,这种错误很少见,并且允许这种错误可以实现许多常见的 JavaScript 模式。
type RestrictToObjectParam = (arg: object) => any;
let fun: RestrictToObjectParam;
fun = (arg: object) => {}; // Ok
fun = (arg: {}) => {}; // Ok
fun = (arg: { str: string }) => {}; // Ok
fun = (arg: { obj: {}; num: number }) => {}; // Ok
fun = (arg: number) => {}; /* Error
~~~
Type '(arg: number) => void' is not assignable to type 'RestrictToObjectParam'.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'object' is not assignable to type 'number'.(2322) */