本来是在网上闲逛看看现在有什么适配React Hooks的库, 发现有一个rxjs-hooks还行. 竟然是LeetCode开源的, 于是就点进去看看. 发现了一个hire的repo.
3, 4做得多了没什么新鲜感, 只能感叹下现在前端招聘确实越来越注重工程化和实用性了, 没想到一个OG网站的前端题竟然没有一个是算法的. 2确实很棒, 反手就把自己项目给改了, 虽然现有的部署方式并不需要这种优化.
题目1确实是挺头疼的一个实际问题. 本来以为在实际工作中用用扁平的基本类型就够用了, 但正如之前写Scala一样, 一入类型深似海啊, 各种头疼的TS Error
. 工作中想写点骚类型看见什么keyof
, Exclude
, Extract
之类就头大, 每次都疯狂搜半天. 做这个题时候正好顺便屡屡清楚.
这道题的描述挺多挺复杂的, 但其实要求精简一下就是:
写出一个改变某个interface的某些属性的类型, 继承其他的属性
的类型.
改来改去后我的最终答案是:
// keys of non-function props: count, message...
type NonFuncKeys = Exclude<keyof EffectModule, keyof Connected>
// extract non-function types from original interface
type NonFuncProps = {
[key in NonFuncKeys]: EffectModule[key]
}
// combine
type Result = Partial<NonFuncProps> & Connected
类型这种东西在js世界里很难说是严谨的, 所以满足要求的答案应该是不止一个, 并且还跟编译器版本有关. 所以关于答案就不深究了. 倒是几种关键字有必要理清除一下.
in
关键字是用来生成Mapped types
的. 作用类似js里的for ... in
, 只不过针对的是属性key
值的Index types
, 实际上是所有公开属性名的Union type
.
用in
把一个类型的所有属性map成any
的例子:
interface Person {
name: string
age: number
}
type ToAny<T> = {
[P in keyof T]: any
}
// or...
type ToAny2<T extends string | number | symbol> = {
[P in T]: any
}
// map name/age to any
type Result = ToAny<Person>
// or
type Result = ToAny2<keyof Person>
keyof
就是👆提到的index type
的query operator
, 类型经过keyof
操作后就得到所有公开属性名的Union type
type PersonKeys = keyof Person // 'name' | 'age'
这个方括号叫indexed access operator
. 这个很好理解了, 经这个操作可以获取类型T
的属性key为K
的类型
type Age = Person['age'] // number
挺常用的工具类型, 字面意思, 没啥难度. 但是Required
的定义就比较骚了:
type Required<T> = {
[P in keyof T]-?: T[P]; // -? 😲
};
这个就是看起来有点屌的类型的, 但其实定义并不复杂, 用法也很简单
type Droid = Pick<Person, 'name'>
type ClonePerson = Pick<Person, 'name' | 'age'>
还有一个Record
, 刚好像Pick
反过来, 生成一个所有属性都是目标类型的新类型. 不知道有啥用不写了.
type Exclude<T, U> = T extends U ? never : T;
type Extract<T, U> = T extends U ? T : never;
这两个最让人头大了, 之前用的时候经常得到一个never
. 不过在搞懂了keyof
之后就没什么问题了. 看定义就知道这两个类型的参数必须T extends U
, 否则就会直接丢给你个never
. 这也就减弱了这两个方法的可用性, 在两个类型没有继承关系的时候必须要经过keyof
转为indexed type
和Pick
操作才能达到字面上的效果. 这也是为啥很多库里面类型声明文件中起手就是一个Omit
或者Substract
.
v2.8引入的语法. 感觉会挺实用. 但是条件语句表达方式有限, 期待扩展.
这个是自己点进lib.d.ts
里看到的, 文档里很难找到(但还是有). 刚看到觉得这个可以解决Vue
中的很多问题, 因为Vue
项目是this
的重度用户. 一搜果然早在v2.5就已经用上了.
还有一些工具类型和关键字, 先不写了. 之前还有使用了@salesforce/ts-types
, 还没来得及仔细看. 就都留到下一篇blog吧.