前端的进化-追悼写TS砸过的键盘

导读 本文从解决问题的角度出发,讲述实际开发过程中遇到的一些困惑和解决方案。 之前尽管读过一些文章,也系统的看过教程,可当TS结合React,在加上个antd还是一头雾水! 有时候TS给出的提示让人崩溃,搜也搜不到!觉得TS麻烦!不知道类型是啥!感觉声明类型和导入太麻烦! 如果你有上述经历不妨看看这篇文章。 正文 一个经典的class组件 import React from "react"; import { Modal } from "antd"; interface AddModalProps { title: string; } interface AddModalState { isVisible: boolean; } class AddModal extends React.PureComponent< AddModalProps, AddModalState > { constructor(props:AddModalProps) { super(props); this.state = { isVisible:true, } } public render() { const { isVisible } = this.state; const { title } = this.props; return ( ); } private onCancel = () => { this.setState({ isVisible: false, }); } } export default AddModal; 声明AddModalProps我可以理解,为啥还要个AddModalState?这不麻烦吗 学习TS最好方式是自己去看定义文件 让我们把鼠标放在PureComponent上按下F12,鼠标悬浮上面也可以得到一些提示 class PureComponent

extends Component { } class Component { AddModalProps 传给了 P,AddModalState 传个了 s,这里泛型起到关键作用,看看都约束了哪些东西 tslint won't let me format the sample code in a way that vscode likes it :( 作者也是有困惑的 用别人的东西心态还是要摆正 一个参数的构造器 constructor(props: Readonly

); 因为我们的构造器是覆盖了它,所以还是要声明类型 setState 函数 setState( state: ((prevState: Readonly, props: Readonly

) => (Pick | S | null)) | (Pick | S | null), callback?: () => void ): void; 这意味着当你setState是出现AddModalState中没有的key,或者类型不一致都会发生错误 this.setState({ isVisible: false, name:"xiaodun" }); 这个提示确实不太容易读... render(): ReactNode; 自定义组件中是对render的 实现,所以不需要声明返回类型,会约束我们的返回 class中定义了一个未实现的方法,可以称之为抽象类 state: Readonly; 不必自己加个Readonly了,效果在于初始化后再一次的赋值 如果你在接口声明中未对属性加?号,没有初始化它会报错 AddModalState里面的引用类型使用时不需要再次声明 新增一个接口 interface Dog{ name:string; age:number; } 会提示你需要哪些属性 避免拼写 image.png 友情提示,有时候看不到是因为其它插件或设置影响到了,比如我打name的时候 image.png 其实name在上面... 使用的时候 image.png 还是泛型,按住Ctrl,把鼠标放到map上点进去 map(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[]; U意味着你还可以约束返回的类型 往上找 interface Array { 使用第三方库时不知道返回啥类型,也不知道要啥类型 使用Modal组件时,onClose还是onCancel记不清楚了,说实话,看官网真的累,同样F12进去 import OriginModal from './Modal'; import { ModalStaticFunctions } from './confirm'; export { ActionButtonProps } from './ActionButton'; export { ModalProps, ModalFuncProps } from './Modal'; declare type Modal = typeof OriginModal & ModalStaticFunctions; declare const Modal: Modal; export default Modal; 这变量名语义化的好,在进入ModalProps image.png 这注释写的好! 可以先写然后自动导入 其实你用<开头的话,会看到这样 我也是刚刚才发现...,原谅我安装了太多自动提示的插件 我今天卸载了三个 有时候你得不到提示,可能是插件正在初始话、电脑CPU过载,比如频繁触发热更新... 我想要ref来控制它的显示 private addModalRef = React.createRef(); 还是泛型 function createRef(): RefObject; 鼠标放在createRef上也会告诉你 在AddModal上定义一个函数 public setVisible = (isVisible: boolean) => { this.setState({ isVisible, }); }; 然后 实在在不行就 // @ts-ignore as any !. (不会是null) 比如类似这种问题,我想自己验证表单 interface APPState { validateStatus: string; } this.state = { validateStatus:"" } image.png 说出来你可能不信,我一开始是进入到定义尝试着把它给导出来,是我想太多... 然后就看到这 declare const ValidateStatuses: ["success", "warning", "error", "validating", ""]; export declare type ValidateStatus = typeof ValidateStatuses[number]; 然后神奇的脑回路就开始爱的魔力转圈圈 其实只要声明的时候改成 interface APPState { validateStatus: ""; } 我记住你了,字符串字面量类型 再看一下Input组件 private onChange = (e) => { console.log(e.target.value); }; 这个e是什么类型呢? 如果你通过`onChange点进去 onChange?: ChangeEventHandler; type ChangeEventHandler = EventHandler>; 不好意思,你看的是 还是要进Input handleChange: (e: React.ChangeEvent) => void; 这表明你这么写是不用声明的 总结 TS虽然是大势所趋,但也要结合项目和团队成员的掌握情况,毕竟前端的业务特性摆在那里,面向对象的开发模式不是很匹配。 规则也没必要搞的过于严格,还在定义接口的时候可能不用TS已经写完了。 TS定义的再好,翻开项目代码注释少的可怜不也很头大。

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):