位置: IT常识 - 正文

TypeScript 报错汇总(typescript event)

编辑:rootadmin
TypeScript 报错汇总 TypeScript 报错汇总

推荐整理分享TypeScript 报错汇总(typescript event),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:typescriptreact,typescript some,typescript event,typescript implements,typescript instanceof,typescript instanceof,typescript instanceof,typescript instanceof,内容如对您有帮助,希望把文章链接给更多的朋友!

在这篇文章中将记录我遇到的ts错误,应该会持续更新。

有时候从错误点入手学习似乎是一个不错的选择,所以也欢迎你私信我一些ts的问题。

一、内置工具1.1 Pick & Partial

先看看Pick和Partial工具的源码:

type Partial<T> = { [P in keyof T]?: T[P];};type Pick<T, K extends keyof T> = { [P in K]: T[P];};

从代码和注释来看,

通过Pick工具根据联合类型数据,筛选泛型T中的属性,通过Partial工具将接口属性都变为可选属性

比如:

interface User { id: number; age: number; name: string;};// 相当于: type PartialUser = { id?: number; age?: number; name?: string; }type PartialUser = Partial<User>// 相当于: type PickUser = { id: number; age: number; }type PickUser = Pick<User, "id" | "age">

现在实现一个需求:筛选出目标接口中的函数属性,删除其他属性。

// 目标接口interface Part { id: number name: string subparts: Part[] firstFn: (brand: string) => void, anotherFn: (channel: string) => string}

首先遍历接口,将非函数类型的属性设置为never,如果是函数类型,取其属性名,然后通过Pick拿到函数类型成员集合:

type FunctionFilterNames<T> = {[K in keyof T]: T[K] extends Function ? K : never}[keyof T]type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>

完整代码:

type FunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>interface Part { id: number name: string subparts: Part[] firstFn: (brand: string) => void, anotherFn: (channel: string) => string}// 过滤出所有的函数key// type FnNames = "firstFn" | "anotherFn"type FnNames = FunctionPropertyNames<Part>// 根据对象的key获取函数接口集合// type FnProperties = {// firstFn: (brand: string) => void;// anotherFn: (channel: string) => string;// }type FnProperties = FunctionProperties<Part>let func: FnProperties = { firstFn: function (brand: string): void { throw new Error("Function not implemented.") }, anotherFn: function (channel: string): string { throw new Error("Function not implemented.") }}

如果需要深 Partial 我们可以通过泛型递归来实现

type DeepPartial<T> = T extends Function ? T : T extends object ? { [P in keyof T]?: DeepPartial<T[P]> } : Ttype PartialObject = DeepPartial<object>1.2 Record

先看看Record工具的源码:

/** * Construct a type with a set of properties K of type T */type Record<K extends keyof any, T> = { [P in K]: T;};

从源码和注释来看,这个工具的目标是:以K中的每个属性作为key值,以T作为value构建一个map结构

比如:

type pets = 'dog' | 'cat';interface IPetInfo { name: string, age: number,}type IPets = Record<pets, IPetInfo>;const animalsInfo: IPets = { dog: { name: 'Ryuko', age: 1 }, cat: { name: 'Ryuko', age: 2 }}

这个案例来源于这篇文章

现在实现一个需求,封装一个http请求:

首先思考请求方法一般需要哪些参数,比如请求类型、data数据、config配置

通过enum枚举几个常见的请求类型,然后每个具体的方法返回值都是一个Promise:

enum IHttpMethods { GET = 'get', POST = 'post', DELETE = 'delete', PUT = 'put',}interface IHttpFn<T = any> { (url: string, config?: AxiosRequestConfig): Promise<T>}// 以enum参数为key,每个key对应一种请求方法// type IHttp = {// get: IHttpFn<any>;// post: IHttpFn<any>;// delete: IHttpFn<any>;// put: IHttpFn<any>;// }type IHttp = Record<IHttpMethods, IHttpFn>;TypeScript 报错汇总(typescript event)

接下来设置一个methods数组,稍后通过reduce方法遍历这个数组,目的是将所有的方法体放在一个对象httpMethods中,形式如下:

httpMethods = { get: [Function ()], post: [Function ()], delete: [Function ()], put: [Function ()]}

最后将httpMethods暴露出去,那么外面就可以通过httpMethods.get(...)等方法直接调用:

const methods = ["get", "post", "delete", "put"];// map为total对象,method为当前遍历到的方法const httpMethods: IHttp = methods.reduce((map: any, method: string) => {map[method] = (url: string, options: AxiosRequestConfig = {...}) => { const { data, ...config } = options; \ return (axios as any)[method](url, data, config) .then((res: AxiosResponse) => { if (res.data.errCode) { //todo something } else { //todo something } }); } },{} )export default httpMethods

完整代码:

enum IHttpMethods { GET = 'get', POST = 'post', DELETE = 'delete', PUT = 'put',}interface IHttpFn<T = any> { (url: string, config?: AxiosRequestConfig): Promise<T>}type IHttp = Record<IHttpMethods, IHttpFn>;const methods = ["get", "post", "delete", "put"];const httpMethods: IHttp = methods.reduce((map: any, method: string) => {map[method] = (url: string, options: AxiosRequestConfig = {...}) => { const { data, ...config } = options; \ return (axios as any)[method](url, data, config) .then((res: AxiosResponse) => { if (res.data.errCode) { //todo something } else { //todo something } }); } },{} )export default httpMethods1.3 Exclude & omit

先看看Exclude和omit工具的源码:

type Exclude<T, U> = T extends U ? never : T;type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

从代码和注释来看:

Exclude可以选出T不存在于U中的类型Omit可以抛弃某对象中不想要的属性

比如:

// 相当于: type A = 'a'type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'>interface User { id: number; age: number; name: string;};// 相当于: type PickUser = { age: number; name: string; }type OmitUser = Omit<User, "id">

举个例子,现在我们想引入第三方库中的组件,可以这样做:

// 获取参数类型import { Button } from 'library' // 但是未导出props typetype ButtonProps = React.ComponentProps<typeof Button> // 获取propstype AlertButtonProps = Omit<ButtonProps, 'onClick'> // 去除onClickconst AlertButton: React.FC<AlertButtonProps> = props => ( <Button onClick={() => alert('hello')} {...props} />)二、类型 “string” 没有调用签名 ts(2349)

函数返回元组的时候,在使用的时候,元素可能是元组中的任意一个类型,比如:

所以,在对返回的元组进行取值操作时,返回值内的类型顺序,可能和函数内的顺序不一致,需要多加一个条件判断:

function test<T>(name: T){let myName = nameconst setName = (newName: T): void => { if(typeof newName === 'string'){ console.log(newName.length); } } // console.log(typeof setName); // function return [myName, setName]}const [myName, setName] = test<string>("Ryuko")// 此表达式不可调用。"string | ((newName: string) => void)" 类型的部分要素不可调用。// 类型 "string" 没有调用签名。ts(2349)// setName("test")// 编译器无法判断setName是string还是一个函数,所以需要通过typeof手动判断if(typeof setName === 'function'){ setName("test") }console.log(myName); //Ryukoexport{}

在这个报错案例中,第四行的typeof newName === 'string'判断也是很重要的知识点,面对联合类型传参的情况,我们常常需要通过类型判断来决定最后要执行哪个方法:

type Name = stringtype NameResolve = (name: string) => stringtype NameOrResolver = Name | NameResolvefunction getName(param: NameOrResolver): Name{ if(typeof param === 'string'){ return param }else{ return param("Ryuko") }}console.log(getName("Ryuko")); // Ryukoconsole.log(getName( (p: string) => { return p + "si" })); // Ryukosi三、类型 “string” 到类型 “number” 的转换可能是错误的ts(2352)// 类型 "string" 到类型 "number" 的转换可能是错误的,因为两种类型不能充分重叠。// 如果这是有意的,请先将表达式转换为 "unknown"// 在那些将取得任意值,但不知道具体类型的地方使用 unknown,而非 any。// let a = 'Ryuko' as number// 更正:先将数据转化为unknown,再将数据转化为子类型的numberlet a = ('Ryuko' as unknown) as numberexport {}

这样的转换方式还可以用来定义html元素,比如我们想要通过dom操作,来改变某个超链接的url路径地址:

可是在HTMLElement元素节点中并不存在src这一属性:

因此,我们可以将这个节点属性断言转化为子属性HTMLImageElement,在子属性身上可以获取到src属性

let elem = document.getElementById('id') as HTMLImageElement四、类型“string”的参数不能赋给类型“Method”的参数。ts(2345)type Method = 'get' | 'post' | 'delete'const requestConfig = { url: 'localhost: 3000', // config 中的 method 是string类型的菜蔬,而 request 方法中的Method参数 // method: 'get' // 解决办法 通过断言进行转换 method: 'get' as Method}function request(url: string, method: Method){ console.log(method);}// 类型“string”的参数不能赋给类型“Method”的参数。ts(2345)request(requestConfig.url, requestConfig.method)export {}4.1 相关案例

这里再介绍一种情况:

注意:这个用法并没有报错

type EventNames = 'click' | 'scroll' | 'mousemove';function handleEvent(ele: Element, event: EventNames) { console.log(event);}handleEvent(document.getElementById("app")!, "click")handleEvent(document.getElementById("app")!, "mousemove")

在这个案例中,你可能会认为我传递过去的"click",以及"mousemove"是字符串,既然是字符串,就应该报错:类型“string”的参数不能赋给类型“EventNames”的参数。ts(2345)。

事实上,这里的字符串参数会被推导为EventNames类型,而在前面的错误案例中,method:get将会被推导为string类型!这也是为什么在错误案例中,我们需要手动

本文链接地址:https://www.jiuchutong.com/zhishi/298589.html 转载请保留说明!

上一篇:【TFS-CLUB社区 第4期赠书活动】〖Flask Web全栈开发实战〗等你来拿,参与评论,即可有机获得(tf fans club)

下一篇:yolov7配置与训练记录(二)(yolov4配置)

  • 华为nova9pro电池多大容量(华为nova9pro电池健康度怎么看)

    华为nova9pro电池多大容量(华为nova9pro电池健康度怎么看)

  • 怎样注销支付宝账号重新注册(怎样注销支付宝商家账户)

    怎样注销支付宝账号重新注册(怎样注销支付宝商家账户)

  • 为什么我的快手作品不能置顶(为什么我的快手作品播放量低)

    为什么我的快手作品不能置顶(为什么我的快手作品播放量低)

  • 微信背景怎么设置全部一样(微信背景怎么设置)

    微信背景怎么设置全部一样(微信背景怎么设置)

  • iphone抬头显示怎么关闭(怎么把苹果抬头显示关掉)

    iphone抬头显示怎么关闭(怎么把苹果抬头显示关掉)

  • 怎样登录qq不用验证码(怎样登录qq不用扫码就能登录)

    怎样登录qq不用验证码(怎样登录qq不用扫码就能登录)

  • 微信号可以换吗(买微信号在哪里买啊)

    微信号可以换吗(买微信号在哪里买啊)

  • 访问控制分为哪三种(访问控制有哪些类型)

    访问控制分为哪三种(访问控制有哪些类型)

  • qq和微信的步数不一致原因(qq步数与微信步数相差太多)

    qq和微信的步数不一致原因(qq步数与微信步数相差太多)

  • 闲鱼扣12分影响大吗(咸鱼被扣了12分)

    闲鱼扣12分影响大吗(咸鱼被扣了12分)

  • 注册qq怎么跳过辅助(注册qq怎么跳过好友辅助验证输入短信)

    注册qq怎么跳过辅助(注册qq怎么跳过好友辅助验证输入短信)

  • ppt2010合并形状不能用(ppt2010合并形状不能用图片)

    ppt2010合并形状不能用(ppt2010合并形状不能用图片)

  • 微信公众号留言不显示(微信公众号留言在哪里找)

    微信公众号留言不显示(微信公众号留言在哪里找)

  • 刚买的笔记本电脑怎么下软件(刚买的笔记本电脑充电要注意什么)

    刚买的笔记本电脑怎么下软件(刚买的笔记本电脑充电要注意什么)

  • 抹掉iphone需要多久(抹掉iphone要多长时间)

    抹掉iphone需要多久(抹掉iphone要多长时间)

  • 爱奇艺买的电影有效期多久(爱奇艺买的电影可以一起看吗)

    爱奇艺买的电影有效期多久(爱奇艺买的电影可以一起看吗)

  • 北京阿里通信是什么(阿里通信官方)

    北京阿里通信是什么(阿里通信官方)

  • 什么是pd充电(什么pd充电器好)

    什么是pd充电(什么pd充电器好)

  • 苹果xsmax抬头灯怎么设置(苹果xsm的抬头灯怎么开启)

    苹果xsmax抬头灯怎么设置(苹果xsm的抬头灯怎么开启)

  • 小米手环深睡时间准确吗(小米手环深睡时长多久正常)

    小米手环深睡时间准确吗(小米手环深睡时长多久正常)

  • w7电脑蓝屏0x0000003b(w7电脑蓝屏0x0000006b)

    w7电脑蓝屏0x0000003b(w7电脑蓝屏0x0000006b)

  • iPhone XR支持横屏吗(iphonexr可以横屏显示嘛)

    iPhone XR支持横屏吗(iphonexr可以横屏显示嘛)

  • 为什么手机会说暂停服务(为什么手机会说气温低将停止)

    为什么手机会说暂停服务(为什么手机会说气温低将停止)

  • 8p怎么返回(8p怎么返回上一级)

    8p怎么返回(8p怎么返回上一级)

  • QQ号怎样解冻(qq号怎样解冻账号)

    QQ号怎样解冻(qq号怎样解冻账号)

  • 百度输入法如何打日语(百度输入法如何翻译英文)

    百度输入法如何打日语(百度输入法如何翻译英文)

  • Linux下多线程下载工具MWget和Axel使用介绍(linux多线程运行)

    Linux下多线程下载工具MWget和Axel使用介绍(linux多线程运行)

  • 9、Linux 高并发Web服务器项目实战(附代码下载地址)(linux 高并发网络编程)

    9、Linux 高并发Web服务器项目实战(附代码下载地址)(linux 高并发网络编程)

  • 织梦模板DEDECMS自定义DIY表单图文教程使用设置方法(织梦模板改成帝国模板)

    织梦模板DEDECMS自定义DIY表单图文教程使用设置方法(织梦模板改成帝国模板)

  • 商贸企业购销混凝土税率怎么选择
  • 契税通过应交税费
  • 贸易公司开发票进项跟销项不符合怎么办
  • 投资收益免征企业所得税
  • 非金融单位贷款利息收入列示什么科目
  • 分公司的税收机关在总公司还是分公司
  • 公司被扣货款怎么记账
  • 环保科技属于什么行业类别
  • 固定收益款可以开增值税专票吗?
  • 别墅一般送车库吗
  • 房地产开发商转型
  • 记账凭证核算形式账务处理程序的基本特点
  • 自建房屋房产税纳税义务发生时间
  • 调整以前年度销售费用会计分录
  • 村集体经济组织法
  • 收到客户不要的定金怎么做账?
  • 工会经费基数是上个月收到的工资还是什么
  • 发票认证但未抵扣需要在报表里填吗
  • 新成立的分公司怎么样
  • 房地产企业预收账款
  • 金银首饰消费税怎么算
  • 为什么增值税发票税率是1%
  • 成立一般纳税人公司有什么好处
  • 企业卖固定资产
  • 财务费用利息收入在损益表中怎么填
  • 生产性生物资产计提折旧的方法
  • 购买机动车怎样抵扣进项税
  • 公司自己的食堂需要办理食品经营许可证吗
  • 城建税上月少计提本月怎么做账
  • 新版edge浏览器文字不显示
  • 企业拆迁补偿款税务最新政策
  • 开具红字发票信息表对方未接受到怎么办
  • 帮公司垫付的钱怎么要
  • 发散思维的关键
  • 电脑eb是什么意思
  • config.cfg是什么文件
  • 企业租赁发票税率是多少2023年
  • 政府性基金和行政事业性收费区别
  • 1.启动前端项目怎么做
  • 用vue做的登录界面
  • 上年未结转的成本今年可以结转吗
  • 企业商誉属于什么资产
  • 划拨建设用地使用权没有使用期限的限制
  • framework core
  • 微软edge插件
  • python中函数的用法
  • 小微企业认定办法
  • 企业向银行借入长期借款,应借记
  • sql函数判断一个值是否是数字
  • 预缴了增值税在申报增值税时申报
  • 待抵扣进项税额和待认证进项税额的区别
  • 公户转私户的钱怎么退回来
  • 员工成本价购买公司商品 税屋
  • 外贸企业汇兑损益如何减少
  • 应收账款的金额包括增值税吗
  • 公司五金是哪五金
  • 注册公司好麻烦
  • 领用材料属于什么会计分录
  • 账实不符怎么调账
  • sql server随机数函数
  • win 9x
  • fedora s9
  • android系统应用可以禁用吗
  • office解压后如何安装
  • win8.1技巧
  • win10每周更新
  • win10每周更新
  • win8.1自带usb3.0驱动吗
  • windows tcp
  • 怎么免费升级win10系统
  • cocos2dx游戏开发教程
  • 2012年腾讯股价多少
  • 简述jquery的优势
  • 安卓手机关掉
  • python 钉钉打卡定位
  • python 批量查询
  • python坑人代码
  • 北京市大兴区有多少人口
  • 金税盘注销后怎么开发票
  • 烟叶税进项抵扣
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设