type TA = "typeA"
type TB = "typeB"
type TC = "typeC"
type HA = (arg: number) => void;
type HB = (arg: string) => void;
type HC = (arg: boolean) => void;
// 目的是为了实现下面这样类似的重载
// 但是感觉重载有些麻烦,万一类型多了,得写一堆,很烦
// 有什么办法通过泛型来表达吗?
function func(type: TA, handler: HA): void;
function func(type: TB, handler: HB): void;
function func(type: TC, handler: HC): void;
1
wisebeer 2020-01-04 14:33:58 +08:00
用 any
|
2
xiaoming1992 OP @wisebeer 大佬!大佬![抱拳]
|
3
des 2020-01-04 15:14:09 +08:00 via Android
泛型
|
4
EridanusSora 2020-01-04 15:36:31 +08:00
type H<T> = (arg: T) => void;
function funcA(type: TA, handler: H<string>): void; function funcB(type: TB, handler: H<number>): void; function funcC(type: TC, handler: H<boolean>): void; |
5
codelegant 2020-01-04 15:37:30 +08:00
TA | TB | TC 与 HA | HB | HC 之前可以通过操作关联起来吗?如果不行,就无法使用泛型。泛型就是用变量捕获类型的声明,然后重用。
|
6
wi 2020-01-04 20:24:07 +08:00 1
interface TMap {
"a": (a: number) => any "b": (b: number | string) => any "c": (c: Date) => any } function fn2<T extends keyof TMap, F extends TMap[T]>(a: T, fn: F) { } |
7
wi 2020-01-04 20:26:44 +08:00 1
function fn3<T extends keyof TMap>(a: T, fn: TMap[T]) {
} 这个也可以 |
8
xiaoming1992 OP |
9
a132811 2020-01-05 09:29:37 +08:00
@wi 请问这里怎么错了啊?
``` $ cat a.ts interface TMap { "a": (a: number) => any "b": (b: number | string) => any "c": (c: Date) => any } function fn2<T extends keyof TMap, F extends TMap[T]>(a: T, fn: F) { console.log(a, fn(1)) } fn2("a",(a:number)=>a) ➜ ts$ git:(master) ✗ $ tsc a.ts a.ts:8:27 - error TS2345: Argument of type '1' is not assignable to parameter of type 'number & Date'. Type '1' is not assignable to type 'Date'. 8 console.log(a, fn(1)) ``` |
10
xiaoming1992 OP @a132811 你这个 fn(1),TMap["c"]是不能接受 1 这个参数的啊。你是 abc 看懵了吧,把 fn2 里面的参数 a 改成 w 或者其他什么符号就清楚一点了
|
11
a132811 2020-01-06 00:13:29 +08:00
@xiaoming1992 你没有看懵了,我确实是不明白。
我的代码里面 fn 的类型就是 TMap["a"]吧,也就是(a: number) => any 吧 fn(1) 中 1 与 a:number 应该能匹配类型才对呀 |
12
a132811 2020-01-06 00:14:13 +08:00
你没有看懵了-〉我没有看懵
|
13
xiaoming1992 OP @a132811 TMap["a"]确实没问题,可是 TMap["c"]是有问题的啊。你在定义 fn2 的时候,console.log(a, fn(1)),不能 fn(1),因为 fn 可能只能接受 Date,你把函数的形参全部改成 w,就能发现自己哪里的问题了
|
14
xiaoming1992 OP interface TMap {
"a": (w: number) => any "b": (w: number | string) => any "c": (w: Date) => any } function fn2<T extends keyof TMap, F extends TMap[T]>(w: T, fn: F) { // 这儿错了,不能直接调用 fn(1) // 当 w == "c"时,fn 不能接受 1 作为参数 console.log(w, fn(1)) } // 你看看,如果上面执行 fn(1) // 那你这么调用是不是就 errer 了? fn2("c", (w: Date) => w.getDate()) // 手机打字好累... |
15
a132811 2020-01-06 10:00:30 +08:00
@xiaoming1992 感谢!
我才想明白,我想成了把 fn:F 想成了执行时 `fn2("a", (n:number)=>n)` 才确定类型 为 number 其实编译 typescript 时, fn:F 的类型就确定必须接受: number|string|Date,少一个都不行 ps:程序员不要熬夜,熬夜太多了,脑子要坏 |
16
xiaoming1992 OP @a132811 熬夜狗枯辣😭
|