export {}
type F =
((a: string) => void) |
((b: boolean) => void)
let f: F = (a: string) => {}
f('foo')
function f2 (f: F) {
f('foo')
^^^^^
}
为什么光标处会出现这个错误呢?
[ts] Cannot invoke an expression whose type lacks a call signature. Type 'F' has no compatible call signatures.
PS. 唉头一次写 typescript 程序,碰到无数问题。typescript 要在本来无类型的 js 上面加类型搞出来的东西貌似比 java 的类型系统坑多(当然也灵活的多)
1
kernel OP 额发现这里应该用&,才能得到正确的 overload 效果
|
2
hst001 2018-10-01 20:04:17 +08:00
这个逻辑看起来就有问题吧,参数类型是 F,然后你就直接 f('foo'),编译器怎么知道你到时候传进来的 f 是 (a: string) => void 还是 (b: boolean) => void ?
|
3
kernel OP @hst001 F 是这二个函数 overload 在一起的效果,当然可以根据参数来自动判断
把 type F = ((a: string) => void) | ((b: boolean) => void) 改成 type F = ((a: string) => void) & ((b: boolean) => void) 就可以了 |
6
hst001 2018-10-01 20:25:59 +08:00
@kernel #5 改成 & 表示取类型交集,换句话说,你等于告诉编译器,你传给 f2 的参数 f 是可以支持同时支持 string 和 boolean,所以就能编译通过了
|
8
VDimos 2018-10-01 22:49:18 +08:00 via Android 1
这个和重载不重载无关,联合类型并不是或的意思,它本身就是一个独立的类型,所以不能直接调用,它没有 call signature。如果你使用交叉类型,两个函数签名交叉类型依旧是函数,所以有 call signature,才能编译。交叉类型不应该用在函数上,这个产生的结果很抽象,应该用在对象上面。你这个类型应该把参数改为 string 和 boolean 的联合类型,而不是独立成两个函数再联合
|
9
NickCarter 2018-10-01 23:27:33 +08:00
type F = (a: string | boolean) => void
|
10
azh7138m 2018-10-01 23:58:28 +08:00
楼上的写法是更好的选择
关于重载,官方文档也有写示例,https://www.typescriptlang.org/docs/handbook/functions.html,可以写完声明,再去写具体的定义 |
11
kernel OP @VDimos &用在多个函数上就是表示的是重载的意思吧。把参数改成 string | boolean 不是个办法,因为可能不同函数参数个数不一样
|
12
VDimos 2018-10-02 11:10:02 +08:00
@kernel &用在函数上很抽象,我在官方文档里也没看见关于这个的讲解。你甚至可以在后面&一个任何类型,在编译时都会当作它有 call signature,但是实际上并没有
|
13
kernel OP @VDimos 我是在搜 issue 列表发现&用在函数上就表示重载(而且不用&还真没有别的办法)。至于为什么一个函数可以&一个非函数而不报错,这可能是 ts 的缺陷吧。
|
14
franklinyu 2018-10-03 10:50:36 +08:00
「搜 issue 列表发现&用在函数上就表示重载」真的?哪个 issue ?很有兴趣知道
|
15
kernel OP |
16
vsomeone 2018-10-03 13:47:06 +08:00
不太懂这个重载是怎么写的… TypeScript 里的重载应该是下面这样吧
```typescript class Person {} class Pet {} class Shop {} type Shopping = { (a: Person): void; (b: Pet, c: Shop): void; }; let shop: Shopping = (a?: Person, b?: Pet, c?: Shop) => { if (a instanceof Person) {} else if (b instanceof Pet && c instanceof Shop) {} } ``` |