最近在写react时定义变量类型时,无意点到了ElementType,然后在node_modules/@types/react/index.d.ts 中发现了这段代码:
牛啊,虽然我没太看懂,但是就是觉得挺牛的。
但是后来咱一Google,发现网上管这个叫类型过滤,是一个实用的TS写法。
来看下面这个例子:
interface Example{
a:string;
b:number;
c:number;
d:string;
...
}
我们有一个Example的接口,但是咱们现在想对这个接口做一些处理,只希望留下类型为string的属性,这样咱们应该咋做?就可以使用咱们自己定义的FilterType。
type newExample = FilterType<Example,string> // {a:string;d:string;...}
咱们来看看FilterType是如何实现的:
type FilterType<Source, Types> = Pick<
Source,
{
[K in keyof Source]: Source[K] extends Types ? K : never
}[keyof Source]
>;
首先咱们先来看看代码中出现的几个utility types。(大佬直接跳过)
in 可以遍历枚举类型,类似 for...in
type Example = 'a' | 'b' | 'c' | 'd'
type Obj = {
[T in Example]: string; // 遍历Example,把每个key都赋值string类型
}
/* 等价于
type Obj = {
a: string;
b: string;
c: string;
d: string;
}
*/
TS官方文档中把它称作索引类型查询操作符,其实就是取到类型的key,类似Object.keys() 虽然我不知道这样类比对不对。
interface Example {
a: string;
b: string;
c: number;
d: boolean;
}
type Keys = keyof Example // 等价于 type Keys = 'a' | 'b' | 'c' | 'd'
interface A {
a:string;
}
interface B extends A {
b:string;
}
// B是否继承于A?若是,则为number类型;若不是,则为string类型
type C = B extends A ? number : string // 等价于 type C = number
先看一个例子,揭开她的面纱,不,是口罩:
type Mask<source,types> = {
[K in keyof source]:source[K] extends types ? K : never;
}
interface Example{
name:string;
height:number
}
type newType = Mask<Example,string> // { name:'name'; height:never}
这时候咱们看到一个{ name:'name'; height:never} ,what??? 这有啥用?
别急!接下来咱们继续看下面这个例子,揭开她的外套:
来看一个可以记在笔记本上的小知识点:索引访问接口属性
type person = {
name:"Angus";
height:185;
}["name" | "height"]
等价于:
type person = "Angus" | 185
注意的是,当value为never时,就会访问不到
type person = {
name:"Angus";
height:185;
girlFriend:never;
}["name" | "height" | "girlFriend"]
等价于
type person = "Angus" | 185
(singleDog的自嘲
那知道了索引访问接口属性有啥用呢?来看下面这个例子,揭开她的clothes:
type Clothes<source,types> = {
[K in keyof source]:source[K] extends types ? K : never;
}[keyof source]
interface Example{
name:string;
height:number;
home:string
}
type newType = Clothes<Example,string> // type newType = "name | home"
这样我们就能拿到我们想要的类型的联合类型。
最后一步,咱们揭开***
hold on ,咱们先了解一下Pick。
Pick是在一个类型对象中,挑选几个类型,组成一个新的的类型。
interface Angus{
name:string;
height:number;
wight:number;
}
type newAngus = Pick<Angus,'name' | 'height'> //{name:string;height:number}
它的实现:
type Pick<T,K extends keyof T> = {
[P in K] : T[P];
}
然后我们来看Google上的那个例子:
type FilterType<Source, Types> = Pick<
Source,
{
[K in keyof Source]: Source[K] extends Types ? K : never
}[keyof Source]
>;
是不是茅厕顿开!!!通过Pick就可以挑选我们想要的属性了。
{
[K in keyof Source]: Source[K] extends Types ? K : never
}[keyof Source]
这两行的代码就能拿到我们想要的属性。再通过Pick一下就完事。有没有被秀到?
那咱们再来看看TS中其他的一些工具类型吧
Omit(a,b) 接收两个参数,第一个是要编辑的基本类型,第二个是你要删除的类型。
type Person = {
name:string;
sex:string;
}
type newPerson = Omit<Person,'name'> // {sex:string}
看看它咋实现的:
type Omit <T,K extends keyof any> = Pick<T,Exclude<keyof T,K>>;
Partial 可以快速把某个接口类型中定义的属性变成可选的(Optional)
type Person = {
name:string;
sex:string;
}
type newPerson = Partial<Person> // {name?:string;sex?:string}
看看它咋实现的:
type Partial <T> = {
[P in keyof T]?: T[P]
}
用于删除类型集合中的指定类型.
type a = string | number
type newPerson = Exclude<a,string> //number
实现:
type Exclude<T, U> = T extends U ? never : T
将接口所有属性变为只读的.
type Person = {
name:string;
sex:string;
}
type newPerson = Readonly<Person>
// type newPerson = {readonly name: string;readonly sex: string;}
实现:
type Readonly<T> = { readonly [P in keyof T]: T[P]; }
ReturnType的作用是用于获取函数 T 的返回类型。
type T0 = ReturnType<() => string>; // string
type T1 = ReturnType<(s: string) => void>; // void
type T2 = ReturnType<() => T>; // {}
type T3 = ReturnType<() => T>; // number[]
type T4 = ReturnType; // any
type T5 = ReturnType; // any
type T6 = ReturnType; // Error
type T7 = ReturnType; // Error
实现:
type ReturnType any> = T extends (...args: any) => infer R ? R : any;
Parameters的作用是用于获取函数 T 的参数类型。
type getuserInfo = (user: string) => void
// Parameters<T>的作用是用于获取函数 T 的参数类型。
type ParametersUserInfo = Parameters<getuserInfo>
作者:Angus安格斯
链接:https://juejin.cn/post/7052949415350239246
如今的 Web 前端已被 React、Vue 和 Angular 三分天下,尽管现在的 jQuery 已不再那么流行,但 jQuery 的设计思想还是非常值得致敬和学习的,特别是 jQuery 的插件化。
受控组件与非受控组件在官网与国内网上的资料都不多,有些人觉得它可有可不有,也不在意。这恰恰显示React的威力,满足不同规模大小的工程需求。
一般在传统模式下,我们构建前端项目很简单。就是下载各种js文件,如JQuery、Echart等,直接放置在html静态文件。Webpack则是JavaScript中比较知名的打包工具。这两个构建工具构成了React应用快速搭建的基础。
Gatsby能快速的使用 React 生态系统来生成静态网站,可以结合React Component、Markdown 和服务端渲染来完成静态网站生成让他更强大。
React推出后,出于不同的原因先后出现三种定义react组件的方式,殊途同归;具体的三种方式:函数式定义的无状态组件、es5原生方式React.createClass定义的组件、es6形式的extends React.Component定义的组件
React主要思想是通过构建可复用组件来构建用户界面,每个组件都有自己的生命周期,它规定了组件的状态和方法需要在哪个阶段改变和执行。所谓组件就是有限状态机,,表示有限个状态以及在这些状态之间的转移和动作行为的模型。
React 相关的优化:使用 babel-react-optimize 对 React 代码进行优化,检查没有使用的库,去除 import 引用,按需打包所用的类库,比如 lodash 、echarts 等.Webpack 构建打包存在的问题两个方面:构建速度慢,打包后的文件体积过大
这篇文章主要介绍React Router定义路由之后如何传值,有关React和React Router 。react router中页面传值的三种方法:props.params、query、state
react 高阶组件简单的理解是:一个包装了另一个基础组件的组件。高阶组件的两种形式:属性代理(Props Proxy)、反向继承 (Inheritance Inversion)
React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!