
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
我的逻辑思维可能太差了
提前感谢点开此贴
1 noe132 Apr 14, 2022 via Android 这是 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 |
2 noe132 Apr 14, 2022 via Android 最后一句有些错误,应该是:在你这个例子里,type T<U> = (v: U) => void |
3 noe132 Apr 14, 2022 via Android 还有一些比较特殊的例子是 invarient 的。最常见的就是可写数组。因为数组的读操作是 corarient ,而写是 contravarient ,2 者结合起来就是 invarient 。 Array<Dog> 可以 push 一个 GrayHound 进去,也可以 pop 一个 animal 出来,但是不能赋值给 Array<Animal> 或者 Array<GrayHound> 的变量,因为前者可能会 push 一个 dog 进去,后者可能会 pop 一个 dog 出来。 |
4 chenluo0429 Apr 14, 2022 via Android 举个栗子: Farther 类型对应的是可以给所有动物洗澡的机器,参数是所有动物。 Son 类型是可以给狗洗澡的机器,参数是狗。 如果你需要一个动物,我可以给你只狗。 如果你需要一台可以给狗洗澡的机器,我可以给你一台能给所有动物洗澡的机器,但是反过来就不对了。 |
5 KMpAn8Obw1QhPoEP Apr 14, 2022 via Android |
6 johnkiller OP |