V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xiaoming1992
V2EX  ›  程序员

请问 typescript 类型声明问题?

  •  
  •   xiaoming1992 · 2020-01-04 14:20:02 +08:00 · 2171 次点击
    这是一个创建于 1567 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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   ·   我们的愿景   ·   实用小工具   ·   5243 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 07:11 · PVG 15:11 · LAX 00:11 · JFK 03:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.