请问 typescript 类型声明问题? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
xiaoming1992
V2EX    程序员

请问 typescript 类型声明问题?

  •  
  •   xiaoming1992 2020-01-04 14:20:02 +08:00 2597 次点击
    这是一个创建于 2116 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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; 
    16 条回复    2020-01-06 12:17:41 +08:00
    wisebeer
        1
    wisebeer  
       2020-01-04 14:33:58 +08:00
    用 any
    xiaoming1992
        2
    xiaoming1992  
    OP
       2020-01-04 14:47:41 +08:00
    @wisebeer 大佬!大佬![抱拳]
    des
        3
    des  
       2020-01-04 15:14:09 +08:00 via Android
    泛型
    EridanusSora
        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;
    codelegant
        5
    codelegant  
       2020-01-04 15:37:30 +08:00
    TA | TB | TC 与 HA | HB | HC 之前可以通过操作关联起来吗?如果不行,就无法使用泛型。泛型就是用变量捕获类型的声明,然后重用。
    wi
        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) {

    }
    wi
        7
    wi  
       2020-01-04 20:26:44 +08:00   1
    function fn3<T extends keyof TMap>(a: T, fn: TMap[T]) {

    }
    这个也可以
    xiaoming1992
        8
    xiaoming1992  
    OP
       2020-01-04 21:19:46 +08:00 via Android
    @EridanusSora 我就是不想用重载啊...

    @wi 真大佬!我一直在想前面的 T 怎么限定,大佬一个 extends 就解决了,感谢!
    a132811
        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))

    ```
    xiaoming1992
        10
    xiaoming1992  
    OP
       2020-01-05 09:41:52 +08:00 via Android
    @a132811 你这个 fn(1),TMap["c"]是不能接受 1 这个参数的啊。你是 abc 看懵了吧,把 fn2 里面的参数 a 改成 w 或者其他什么符号就清楚一点了
    a132811
        11
    a132811  
       2020-01-06 00:13:29 +08:00
    @xiaoming1992 你没有看懵了,我确实是不明白。
    我的代码里面 fn 的类型就是 TMap["a"]吧,也就是(a: number) => any 吧

    fn(1) 中 1 与 a:number 应该能匹配类型才对呀
    a132811
        12
    a132811  
       2020-01-06 00:14:13 +08:00
    你没有看懵了-〉我没有看懵
    xiaoming1992
        13
    xiaoming1992  
    OP
       2020-01-06 00:42:38 +08:00 via Android
    @a132811 TMap["a"]确实没问题,可是 TMap["c"]是有问题的啊。你在定义 fn2 的时候,console.log(a, fn(1)),不能 fn(1),因为 fn 可能只能接受 Date,你把函数的形参全部改成 w,就能发现自己哪里的问题了
    xiaoming1992
        14
    xiaoming1992  
    OP
       2020-01-06 00:48:27 +08:00 via Android
    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())

    // 手机打字好累...
    a132811
        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:程序员不要熬夜,熬夜太多了,脑子要坏
    xiaoming1992
        16
    xiaoming1992  
    OP
       2020-01-06 12:17:41 +08:00 via Android
    @a132811 熬夜狗枯辣
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1202 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 17:44 PVG 01:44 LAX 10:44 JFK 13:44
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86