仅接受对象类型的函数的 TypeScript 类型

问题描述 投票:0回答:1

有没有一种方法可以定义 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 中函数类型的一般工作方式。

javascript typescript
1个回答
0
投票

这是由比较函数类型时的函数参数双方差造成的。在

strictFunctionTypes
模式下,编译器选项
true
 默认为 
strict
,但您可以将其设置为
false
以实现所需的兼容性行为 — 但是,请注意文档中的警告:

函数参数双方差

比较函数参数类型时,如果源参数可分配给目标参数,则分配成功,反之亦然。这是不合理的,因为调用者最终可能会得到一个采用更专业化类型的函数,但会使用不太专业化的类型调用该函数。实际上,这种错误很少见,并且允许这种错误可以实现许多常见的 JavaScript 模式。

TS游乐场

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) */
© www.soinside.com 2019 - 2024. All rights reserved.