Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

精读《Typescript infer 关键字》 #346

Closed
ascoders opened this issue Aug 18, 2021 · 12 comments
Closed

精读《Typescript infer 关键字》 #346

ascoders opened this issue Aug 18, 2021 · 12 comments

Comments

@ascoders
Copy link
Owner

ascoders commented Aug 18, 2021

本周精读的文章是 conditional-infer。infer 这个关键字工作中比较少用到,但需要进行类型编程时却是必不可少的,本周我们一起学习一下吧。


精读《Typescript infer 关键字》

@feikerwu
Copy link
Contributor

image
这里有个问题想讨论下,A 和 B 逆变为 A & B类型,根据集合论,也就是 A B交集,这种不是类型收敛吗,看到文章里把逆变看作类型发散,有点疑惑

@ascoders
Copy link
Owner Author

& 在 TS 里是并,| 是或的含义,不能套用集合含义。

另外类型收敛是指,TS 在类型推导时大部分情况是类型收敛的(收敛最类型安全),这也符合协变的规则(| 表示或,非 A 即 B 就是收敛)。

@07akioni
Copy link
Contributor

image
这里有个问题想讨论下,A 和 B 逆变为 A & B类型,根据集合论,也就是 A B交集,这种不是类型收敛吗,看到文章里把逆变看作类型发散,有点疑惑

这里确实容易引发歧义,因为没说清楚收敛的 source 和 target。

通俗说,协变就是满足约束多、或者说派生程度高的(人a)能赋值给约束少、或者说派生程度少的(动物b)值。

const a: 人 = ...
const b: 动物 = a

你也可以说 b 可以接受一个更收敛的值,也可以说 a 被赋给了更发散的变量。

@fuxiang123
Copy link

文中的例子
type GetLabelTypeFromObject<T> = T extends ? { label: infer R } ? R : never
第一个问号是不是多余的?

@07akioni
Copy link
Contributor

07akioni commented Aug 24, 2021

文中的例子
type GetLabelTypeFromObject<T> = T extends ? { label: infer R } ? R : never
第一个问号是不是多余的?

没毛病

补充:我说的没毛病是说确实是多余的 @zhangyu1818

@soeasyjx
Copy link

soeasyjx commented Aug 25, 2021

type Bar<T> = T extends { a: (x: infer U) => void; b: (x: infer U) => void }? U : never

type T21 = Bar<{ a: (x: string) => void; b: (x: number) => void }>;

请问你确定这个 T21 为 string & number 么?????????

@zhangyu1818
Copy link

楼上说的代码我放ts playground的结果是never,确实让人有一些疑惑
还有type GetLabelTypeFromObject<T> = T extends ? { label: infer R } ? R : never这个也会报错,第一个问号难道不是多余的吗?看见大佬们的发言让我对自己产生了疑惑,都不敢肯定自己了

@feikerwu
Copy link
Contributor

楼上说的代码我放ts playground的结果是never,确实让人有一些疑惑
还有type GetLabelTypeFromObject<T> = T extends ? { label: infer R } ? R : never这个也会报错,第一个问号难道不是多余的吗?看见大佬们的发言让我对自己产生了疑惑,都不敢肯定自己了

number & string 的结果就是never,你可以用其它的例子来验证

@zhangyu1818
Copy link

@feikerwu 想了下结果确实是number & string,但没有类型同时是number和string又变成了never

@ascoders
Copy link
Owner Author

文中的例子
type GetLabelTypeFromObject<T> = T extends ? { label: infer R } ? R : never
第一个问号是不是多余的?

是多余的,已经修复啦,谢谢!

@soeasyjx
Copy link

soeasyjx commented Aug 26, 2021 via email

@soeasyjx
Copy link

soeasyjx commented Aug 26, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants