求助 TypeScript 中关于函数参数类型约束的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
johnkiller

求助 TypeScript 中关于函数参数类型约束的问题

  •  
  •   johnkiller Apr 14, 2022 1182 views
    This topic created in 1476 days ago, the information mentioned may be changed or developed.
    type Assignable<T, U> = T extends U ? true : false type Father = (a: Record<string, any>) => void type Son = (a: { count: number }) => void type R1 = Assignable<Son, Father> // false type R2 = Assignable<Father, Son> // true type R3 = Assignable<Parameters<Son>, Parameters<Father>> // true type R4 = Assignable<{ count: number }, Record<string, any>> // true 

    { count: number }可以赋给( TypeScript 官方叫它 assignable )类型Record<string, any>我能理解没问题,
    但为什么放到函数的参数里就反过来了呢?
    Son 不应该也是 Father 的子类型吗?

    附上 playgorund: https://reurl.cc/12nVGV

    我的逻辑思维可能太差了
    提前感谢点开此贴

    Supplement 1    Apr 14, 2022
    已弄明白,此贴终结。

    如果有同样疑问的 TypeScripter 可以参考前 5 楼回复~
    6 replies    2022-04-14 21:44:47 +08:00
    noe132
        1
    noe132  
       Apr 14, 2022 via Android   2
    这是 Covariance and contravariance 的区别。
    比如我们说 dog extends animal
    如果一个函数调用接受一个 animal ,那么你传 dog 是没有问题的。
    但是如果一个函数调用接受一个 callback ,这个 callback 会收到一个 animal ,如果你传一个收到 dog 的 callback 就不行。因为 callback 的调用方有可能会给你一个 animal ,但 animal 不是 dog 。
    针对类型 T ,如果说 T<dog> extends T<animal> 则 T 是 covarient 。如果 T<animal> extends T<dog>,则 T 是 contravariant 。在你这个例子里,T = (v: T) => void
    noe132
        2
    noe132  
       Apr 14, 2022 via Android
    最后一句有些错误,应该是:在你这个例子里,type T<U> = (v: U) => void
    noe132
        3
    noe132  
       Apr 14, 2022 via Android   1
    还有一些比较特殊的例子是 invarient 的。最常见的就是可写数组。因为数组的读操作是 corarient ,而写是 contravarient ,2 者结合起来就是 invarient 。
    Array<Dog> 可以 push 一个 GrayHound 进去,也可以 pop 一个 animal 出来,但是不能赋值给 Array<Animal> 或者 Array<GrayHound> 的变量,因为前者可能会 push 一个 dog 进去,后者可能会 pop
    一个 dog 出来。
    chenluo0429
        4
    chenluo0429  
       Apr 14, 2022 via Android   1
    举个栗子:
    Farther 类型对应的是可以给所有动物洗澡的机器,参数是所有动物。
    Son 类型是可以给狗洗澡的机器,参数是狗。
    如果你需要一个动物,我可以给你只狗。
    如果你需要一台可以给狗洗澡的机器,我可以给你一台能给所有动物洗澡的机器,但是反过来就不对了。
    johnkiller
        6
    johnkiller  
    OP
       Apr 14, 2022
    @chenluo0429
    @enchilada2020
    @noe132

    非常感谢三位,总算看明白了。
    Aout     Help     Advertise     Blog     API     FAQ     Solana     3249 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 37ms UTC 13:21 PVG 21:21 LAX 06:21 JFK 09:21
    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